码迷,mamicode.com
首页 > 其他好文 > 详细

二分图

时间:2017-08-09 13:04:42      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:pen   src   开始   bool   iostream   while   分享   false   color   

1.

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>

#define N 202

using 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 555

using 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

 

二分图

标签:pen   src   开始   bool   iostream   while   分享   false   color   

原文地址:http://www.cnblogs.com/L-Memory/p/7324178.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!