#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stack>
#include<vector>
#define maxn 5005
#define maxm 100005
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
stack<int>s;
vector<int>vc[maxn];
int ca,n,m,bcnt,e,first[maxn],ev[maxm],next[maxm],index;
int dfn[maxn],low[maxn],belong[maxn],x[maxm],y[maxm],mat[maxn];
int instack[maxn],vis[maxn];
void tarjan(int u)
{
int v;
dfn[u]=low[u]=++index;
s.push(u);
instack[u]=1;
for(int i=first[u];i!=-1;i=next[i])
{
v=ev[i];
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(instack[v])
low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
bcnt++;
do{
v=s.top();
belong[v]=bcnt;
instack[v]=0;
s.pop();
}while(v!=u);
}
}
bool find(int u)
{
int v;
for(int e=0;e<vc[u].size();e++)
{
v=vc[u][e];
if(vis[v]) continue;
vis[v]=1;
if(mat[v]==-1||find(mat[v]))
{
mat[v]=u;
return 1;
}
}
return 0;
}
int Hungary(int nx)
{
int Max=0;
clr(mat,-1);
for(int i=1;i<=nx;i++)
{
clr(vis,0);
if(find(i))
Max++;
}
return Max;
}
void add(int u,int v)
{
next[e]=first[u],ev[e]=v,first[u]=e++;
}
void init()
{
clr(first,-1);
e=1;
bcnt=0;
index=0;
clr(dfn,0);
clr(low,0);
clr(instack,0);
clr(belong,0);
while(!s.empty()) s.pop();
}
int main()
{
//freopen("D:/d.txt","r",stdin);
scanf("%d",&ca);
while(ca--)
{
init();
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d %d",&x[i],&y[i]);
add(x[i],y[i]);
}
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);
if(bcnt==1)
{
puts("1");
continue;
}
for(int i=0;i<=bcnt;i++)
vc[i].clear();
for(int i=1;i<=m;i++)
{
int u=belong[x[i]];
int v=belong[y[i]];
if(u!=v)
vc[u].push_back(v);
}
printf("%d\n",bcnt-Hungary(bcnt));
}
return 0;
}
hdu 3861 The King’s Problem 强连通+二分匹配
最新推荐文章于 2018-10-16 01:25:52 发布