hdu 3861 The King’s Problem 强连通+二分匹配

来源:互联网 发布:js移动轨迹 编辑:程序博客网 时间:2024/05/19 02:21
                     
#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;}

原创粉丝点击