zoukankan      html  css  js  c++  java
  • 11419 SAM I AM(二分图)

    很明显的二分图,只是这题需要输出最小覆盖的点

    我们可以在求出最大匹配之后,以未覆盖的x点进行标记,沿着未覆盖->覆盖->未覆盖->覆盖...的路径标记,最后S中未标记的和T中标记的点构成最小点覆盖集。

    // File Name: 11419.cpp
    // Author: zlbing
    // Created Time: 2013/3/1 14:20:03
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define MAXN 1050
    int Left[MAXN];
    int w[MAXN][MAXN];
    bool S[MAXN],T[MAXN];
    int N,M;
    bool match(int i)
    {
        S[i]=true;
        for(int j=1;j<=M;j++)if(w[i][j]&&!T[j])
        {
            T[j]=true;
            if(Left[j]==0||match(Left[j]))
            {
                Left[j]=i;
                return true;
            }
        }
        return false;
    }
    void dfs(int i)
    {
        S[i]=true;
        for(int j=1;j<=M;j++)if(w[i][j]&&!T[j])
        {
            T[j]=true;
            dfs(Left[j]);
        }
    }
    
    int main(){
        int t;
        while(~scanf("%d%d%d",&N,&M,&t))
        {
            if(N==0&&M==0&&t==0)break;
            int a,b;
            CL(w,0);
            for(int i=0;i<t;i++)
            {
                scanf("%d%d",&a,&b);
                w[a][b]=1;
            }
            CL(Left,0);
            int sum=0;
            for(int i=1;i<=N;i++)
            {
                CL(S,0);
                CL(T,0);
                if(match(i))sum++;
            }
    
            bool c[MAXN];
            CL(c,0);
            for(int i=1;i<=M;i++)c[Left[i]]=1;
            CL(S,0);CL(T,0);
            for(int i=1;i<=N;i++)
                if(!c[i])dfs(i);
            printf("%d",sum);
            for(int i=1;i<=N;i++)
                if(!S[i])printf(" r%d",i);
            for(int i=1;i<=M;i++)
                if(T[i])printf(" c%d",i);
            printf("\n");
        }
        return 0;
    }
  • 相关阅读:
    【NOIP2017】蚯蚓
    【CF407B】Long Path
    【NOIP2017】奶酪
    【NOIP2018】赛道修建(正解)
    【NOIP2018】旅行
    【SDOI2010】地精部落
    【NOIP2017】逛公园
    百度云网盘进行注销操作
    百度超级会员租借.我租给你。
    如何在dos中运行java中的jar包
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2938986.html
Copyright © 2011-2022 走看看