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

二分图匹配

时间:2014-05-02 20:57:04      阅读:359      评论:0      收藏:0      [点我收藏+]

标签:blog   class   code   int   string   2014   

HDU  2063

 求一个二分图的最大匹配。

完全的裸题。贴代码。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
vector<int> G[1005];
bool check[1005];
int mac[1005];
int n;
void add_edge(int from,int to)
{
    G[from].push_back(to);
    G[to].push_back(from);
}
bool dfs(int u)
{
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        if(!check[v])
        {
            check[v]=1;
            if(mac[v]==-1||dfs(mac[v]))
            {
                mac[u]=v;
                mac[v]=u;
                return 1;
            }
        }
    }
    return 0;
}
int xyl()
{
    int ans=0;
    memset(mac,-1,sizeof(mac));
    for(int i=1;i<=n;i++)
    {
        if(mac[i]==-1)
        {
            memset(check,0,sizeof(check));
            if(dfs(i))
            {
                ans++;
            }
        }
    }
    return ans;
}
int main()
{
    int k,n1,m1;
    while(scanf("%d",&k)!=EOF)
    {
        if(k==0) return 0;
        scanf("%d%d",&n1,&m1);
        n=n1+m1;
        for(int i=1;i<=n;i++)
            G[i].clear();
        while(k--)
        {
            int A,B;
            scanf("%d%d",&A,&B);
            add_edge(A,B+n1);
        }
        printf("%d\n",xyl());
    }
}

HDU 2444

判断该图是否为二分图,如果是二分图就求该图的最大匹配。

判断是否为二分图是我用了一个DFS 也不知道还有没有更简单的方法。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<stack>
#include<math.h>
#include<iostream>
using namespace std;
vector<int> G[205];
bool check[205];
int mac[205];
int re[205];
void add_edge(int from,int to)
{
    G[from].push_back(to);
    G[to].push_back(from);
}
bool rdfs(int u,int k)
{
    re[u]=k;
    bool flag=true;
    int k1;
    if(k==1) k1=2;
    else k1=1;
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        if(re[v]==k)
        {
            flag=false;
            break;
        }
        else if(re[v]==0)
        {
            flag=rdfs(v,k1);
            if(!flag)
                break;
        }
    }
    return flag;
}
bool dfs(int u)
{
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        if(!check[v])
        {
            check[v]=true;
            if(mac[v]==-1||dfs(mac[v]))
            {
                mac[u]=v;
                mac[v]=u;
                return true;
            }
        }
    }
    return false;
}
int n;
int xyl()
{
    int ans=0;
    memset(mac,-1,sizeof(mac));
    for(int i=1;i<=n;i++)
    {
        if(mac[i]==-1)
        {
            memset(check,0,sizeof(check));
            check[i]=1;
            if(dfs(i))
                ans++;
        }
    }
    return ans;
}
int main()
{
    int m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;i++)
            G[i].clear();
        while(m--)
        {
            int A,B;
            scanf("%d%d",&A,&B);
            add_edge(A,B);
        }
        memset(re,0,sizeof(re));
        bool flag=0;
        for(int i=1;i<=n;i++)
        {
            if(re[i]==0)
            {
                if(!rdfs(i,1))
                {
                    flag=1;
                    break;
                }
            }
        }
        if(flag==1) printf("No\n");
        else
        {
            printf("%d\n",xyl());
        }
    }
}

HDU 1281

题意:一个棋盘上有一些地方能放“车” 求最多能放多少个,又有多少个点是关键点,关键点——删除这个点能放的“车”会变少。

把行归位X集合 列归为Y集合。每个点就是从X-Y的一条边。

进行二分图匹配。然后枚举边,求出删除这条边之后的最大匹配,如果比之前的少了 就是关键点。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
int mac[205];
bool check[205];
vector<int> G[205];
int z,y;
int n;
int k[10005][2];
void add_edge(int from,int to)
{
    G[from].push_back(to);
    G[to].push_back(from);
}
bool dfs(int u)
{
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        if((u==z&&v==y)||(u==y&&v==z)) continue;
        if(!check[v])
        {
            check[v]=1;
            if(mac[v]==-1||dfs(mac[v]))
            {
                mac[u]=v;
                mac[v]=u;
                return true;
            }
        }
    }
    return false;
}
int xyl()
{
    memset(mac,-1,sizeof(mac));
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        if(mac[i]==-1)
        {
            memset(check,0,sizeof(check));
            if(dfs(i))
                ans++;
        }
    }
    return ans;
}
int main()
{
    int N,M,K;
    int Case=0;
    while(scanf("%d%d%d",&N,&M,&K)!=EOF)
    {
        for(int i=1;i<=N+M;i++)
            G[i].clear();
            int r=0;
            n=N+M;
        while(K--)
        {
            int A,B;
            scanf("%d%d",&A,&B);
            k[r][0]=A;
            k[r][1]=B+N;
            r++;
            add_edge(A,B+N);
        }
        z=0;y=0;
        int ans=xyl();
        //printf("%d\n",ans);
        int sum=0;
        for(int i=0;i<r;i++)
        {
            z=k[i][0];
            y=k[i][1];
            int ans1=xyl();
            if(ans1!=ans)
            {
                sum++;
            }
        }
        printf("Board %d have %d important blanks for %d chessmen.\n",++Case,sum,ans);
    }
}


二分图匹配,布布扣,bubuko.com

二分图匹配

标签:blog   class   code   int   string   2014   

原文地址:http://blog.csdn.net/u012896700/article/details/24850051

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