1 3 2 1 2 1 3
2
#include"stdio.h"
#include"string.h"
#include"queue"
#include"vector"
#include"algorithm"
using namespace std;
#define N 5005
#define M 100005
#define min(a,b) (a<b?a:b)
vector<int>g[N];
struct node
{
int u,v,next;
}e[M];
int t,stop,index,bcnt,head[N],link[N];
int mark[N],dfn[N],low[N],stap[N],be[N];
bool vis[N];
int find(int k)
{
int i,v;
for(i=0;i<g[k].size();i++)
{
v=g[k][i];
if(!vis[v])
{
vis[v]=true;
if(link[v]==-1||find(link[v]))
{
link[v]=k;
return 1;
}
}
}
return 0;
}
void add(int u,int v)
{
e[t].u=u;
e[t].v=v;
e[t].next=head[u];
head[u]=t++;
}
void tarjan(int u)
{
int i,v;
dfn[u]=low[u]=++index;
stap[++stop]=u;
mark[u]=1;
for(i=head[u];i!=-1;i=e[i].next)
{
v=e[i].v;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(mark[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
bcnt++;
do
{
v=stap[stop--];
mark[v]=0;
be[v]=bcnt;
}
while(u!=v);
}
}
void solve(int n)
{
int i;
index=bcnt=stop=0;
memset(dfn,0,sizeof(dfn));
for(i=1;i<=n;i++)
{
if(!dfn[i])
tarjan(i);
}
}
void work(int n)
{
int i,j,u,v;
for(i=0;i<N;i++)
g[i].clear();
for(i=1;i<=n;i++)
{
u=be[i];
for(j=head[i];j!=-1;j=e[j].next)
{
v=be[e[j].v];
if(u!=v)
{
g[u].push_back(v);
// g[v].push_back(u);
}
}
}
int ans=0;
memset(link,-1,sizeof(link));
for(i=1;i<=bcnt;i++)
{
memset(vis,false,sizeof(vis));
ans+=find(i);
}
printf("%d\n",bcnt-ans);
}
int main()
{
int T,n,m,u,v,i;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
t=0;
memset(head,-1,sizeof(head));
for(i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
}
solve(n);
//printf("bcnt%d\n",bcnt);
work(n);
}
return 0;
}hdu 3861 The King’s Problem (强连通+最小路径覆盖),布布扣,bubuko.com
hdu 3861 The King’s Problem (强连通+最小路径覆盖)
原文:http://blog.csdn.net/u011721440/article/details/38496587