zoukankan      html  css  js  c++  java
  • uva 11419 (二分图最小覆盖)

    二分图最小覆盖数=最大匹配数

    建模后即可

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;

    struct my{
       int next;
       int v;
    };

    const int maxn=1000000+10;
    const int maxn2=1000+5;
    my bian[maxn];
    int adj[maxn];
    int s[maxn2];
    int t[maxn2];
    int n,m;
    int left[maxn2];
    int right[maxn2];
    int fa;
    int top1;
    int top2;
    int ansx[maxn2],ansy[maxn2];

    void init(){
       memset(bian,0,sizeof(bian));
       memset(adj,0,sizeof(adj));
       fa=0;
    }

    void myinsert(int u,int v){
         bian[++fa].v=v;
         bian[fa].next=adj[u];
         adj[u]=fa;
    }

    bool match(int i){
         s[i]=true;
         for (int j=adj[i];j;j=bian[j].next){
            int v=bian[j].v;
            if(!t[v]){
                t[v]=true;
                if(left[v]==-1 || match(left[v])){
                    left[v]=i;
                    right[i]=v;
                    return true;
                }
            }
         }
         return false;
    }

    int KM(){
        top1=0;
        memset(left,-1,sizeof(left));
        memset(right,-1,sizeof(right));
         int ans=0;
         for (int i=1;i<=n;i++){
                memset(s,0,sizeof(s));
                memset(t,0,sizeof(t));
                if(match(i))
                            ans++;
            }
        memset(s,0,sizeof(s));
        memset(t,0,sizeof(t));
         for (int i=1;i<=n;i++){
            if(right[i]==-1) match(i);
         }
         for (int i=1;i<=n;i++) if(!s[i]) ansx[++top1]=i;
         top2=0;
         for (int j=1;j<=m;j++) if(t[j]) ansy[++top2]=j;
         return ans;
    }

    void print()
    {
        for (int i=1;i<=top1;i++) printf(" r%d",ansx[i]);
        for (int j=1;j<=top2;j++) printf(" c%d",ansy[j]);
        printf(" ");
    }

    int main(){
        int R,C,N,r,c;
        while(scanf("%d%d%d",&R,&C,&N) && R && C && N){
                init();
            n=R;
            m=C;
            for (int i=1;i<=N;i++){
                scanf("%d%d",&r,&c);
                myinsert(r,c);
            }
            printf("%d",KM());
            print();
        }
    return 0;
    }

  • 相关阅读:
    裴蜀定理
    欧几里得算法
    最大公约数
    质数和合数
    整除
    CSP斗地主
    skkyk:点分治
    题解:P2130 狂奔的Wzf
    题解:最大子树和
    博客大换主题祭
  • 原文地址:https://www.cnblogs.com/lmjer/p/8384236.html
Copyright © 2011-2022 走看看