首页 > 代码库 > 二分图

二分图

1.

技术分享
#include<iostream>#include<cstdio>#include<cstring>#define N 202using namespace std;int Li[N],vis[N],con[N][N];int n,m,ans,f,x;bool dfs(int x){    for(int i=1;i<=m;i++)    {        if(con[x][i] && !vis[i])        {            vis[i]=1;            if(!Li[i] || dfs(Li[i]))            {                Li[i]=x;                return true;            }        }    }    return false;}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)    {        scanf("%d",&f);        for(int j=1;j<=f;j++)        {            scanf("%d",&x);            con[i][x]=1;        }    }    for(int i=1;i<=n;i++)    {        memset(vis,0,sizeof vis);        if(dfs(i)) ans++;    }    printf("%d\n",ans);    return 0;}
P1894

 2.

技术分享
/*开始把边取反,然后跑一边匈牙利算法,然后判断是不是完美匹配(概念网上自己去找),不是就直接输出none;第二步每次删掉一条边,判断是不是完美匹配,不是就输出这个两个点;第二步跑完之后没有发现有一个是可以输出的,就输出none;*/#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#define N 555using namespace std;int mx[N],Li[N],head[N];int n,cut_x,cut_y,S[N],T[N],num,flag=0;bool vis[N],k[N][N];struct node{    int u;    int to;    int next;} e[N<<1];void add(int u,int to){    e[++num].to=to;e[num].next=head[u];head[u]=num;}int dfs(int x){    int v;    for (int i=head[x];i!=0;i=e[i].next)    {        v=e[i].to;        if(x==cut_x && v==cut_y) continue;        if(vis[v]==true) continue;        vis[v]=true;        if(Li[v]==0 || dfs(Li[v]) )        {            mx[x]=v;            Li[v]=x;            return 1;        }    }    return 0;}int maxmatch(){    int ans=0;    for (int i=1;i<=n;i++)    {        for (int j=1;j<=n;j++) vis[j]=false;        ans+=dfs(i);    }    return ans;}void Impotant_edge(){    int ans;    for (int i=1;i<=n;i++)    {        S[i]=i;T[i]=mx[i];    }    for (int i=1;i<=n;i++)    {        cut_x=S[i];cut_y=T[i];        for (int j=1;j<=n;j++) mx[j]=0,Li[j]=0;        ans=maxmatch();        if (ans!=n)        {            printf("%d %d\n",cut_x,cut_y);            flag=1;        }    }    return;}int main(){    int ans,x,y;    scanf("%d",&n);    while(1)    {        scanf("%d%d",&x,&y);        if (x==0&&y==0) break;        k[x][y]=1;    }    for(int i=1; i<=n; i++)        for(int j=1; j<=n; j++)            if( k[i][j]==0 ) add(i,j);    ans=maxmatch();    if (ans!=n)    {        cout<<"none"<<endl;        return 0;    }    else    {        Impotant_edge();        if (flag==0)  cout<<"none"<<endl;        return 0;    }}
codevs1222

 

二分图