zoukankan      html  css  js  c++  java
  • BZOJ 3546: [ONTAK2010]Life of the Party

    Description

    一个二分图最大匹配,求出所有关键点.(n,mleqslant 10^4,kleqslant 10^5)

    Solution

    二分图匹配.

    2015年国家队论文集 - 浅谈图的匹配算法及其应用 陈胤伯

    Code

    /**************************************************************
        Problem: 3546
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:1844 ms
        Memory:14436 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    using namespace std;
     
    #define mpr make_pair
     
    const int N = 20050;
    const int M = 100050;
    const int oo = 0x3fffffff;
     
    inline int in(int x=0,char s=getchar()) { while(s>'9'||s<'0')s=getchar();
        while(s>='0'&&s<='9')x=x*10+s-'0',s=getchar();return x; }
     
    struct Network {
        struct Edge { int fr,to,fl; }edge[M<<3];
        vector<int> g[N];
        int S,T,flow,ce,k;
        int d[N],p[N],cur[N];
         
        void AddEdge(int fr,int to,int fl) {
            edge[ce++]=(Edge) { fr,to,fl },edge[ce++]=(Edge) { to,fr,0 };
            g[fr].push_back(ce-2),g[to].push_back(ce-1);
        }
        int BFS() {
            memset(d,0xff,sizeof(d));
            queue<int> q;
            d[S]=0,q.push(S);
            for(int x;!q.empty();) {
                x=q.front(),q.pop();
                for(int i=0;i<(int)g[x].size();i++) {
                    Edge &e=edge[g[x][i]];
                    if(e.fl && d[e.to]==-1) d[e.to]=d[x]+1,q.push(e.to);
                }
            }return d[T]!=-1;
        }
        int Dinic() {
            for(int x;BFS();) {
                for(k=0,x=S,memset(cur,0,sizeof(cur));;) {
                    if(x==T) {
                        int mine=0,minf=oo;
                        for(int i=0;i<k;i++) if(edge[p[i]].fl<minf) minf=edge[p[i]].fl,mine=i;
                        for(int i=0;i<k;i++) edge[p[i]].fl-=minf,edge[p[i]^1].fl+=minf;
                        k=mine,x=edge[p[mine]].fr,flow+=minf;
                    }
                    for(int &i=cur[x];i<(int)g[x].size();i++) {
                        Edge &e=edge[g[x][i]];
                        if(e.fl && d[e.to]==d[x]+1) break;
                    }if(cur[x]<(int)g[x].size()) {
                        p[k++]=g[x][cur[x]],x=edge[g[x][cur[x]]].to;
                    } else {
                        if(!k) break;
                        d[x]=-1,x=edge[p[--k]].fr;
                    }
                }
            }return flow;
        }
    }py;
     
    struct Gph {
        vector<int> g[N];
        int vis[N];
         
        void clr() { memset(vis,0,sizeof(vis));for(int i=0;i<N;i++) g[i].clear(); }
        void AddEdge(int fr,int to) { g[fr].push_back(to); }
        void DFS(int u) {
            if(vis[u]) return;vis[u]=1;
            for(int i=0;i<(int)g[u].size();i++) DFS(g[u][i]);
        }
        void outE(int n) {
            for(int i=1;i<=n;i++) {
                cout<<i<<" --> ";
                for(int j=0;j<(int)g[i].size();j++) cout<<g[i][j]<<" ";cout<<endl;
            }
        }
    }pn;
     
    int n,m,k,cp;
    pair<int,int> pr[N];
    int L[N];
     
    int main() {
        n=in(),m=in(),k=in();
        for(int i=1;i<=k;i++) {
            int u=in(),v=in();
            py.AddEdge(u,v+n,1);
        }
        py.S=0,py.T=n+m+1;
        for(int i=1;i<=n;i++) py.AddEdge(py.S,i,1);
        for(int i=1;i<=m;i++) py.AddEdge(i+n,py.T,1);
        py.Dinic();
    //  cout<<py.Dinic()<<endl;
        for(int i=0;i<2*k;i+=2) if(py.edge[i^1].fl) 
            pr[++cp]=mpr(py.edge[i].fr,py.edge[i].to);
    //  cout<<"---"<<endl;
         
        memset(L,0,sizeof(L));
        for(int i=1;i<=cp;i++) L[pr[i].first]=pr[i].second;
        for(int i=0;i<2*k;i+=2) {
            if(L[py.edge[i].fr]!=py.edge[i].to) pn.AddEdge(py.edge[i].fr,py.edge[i].to);
            else pn.AddEdge(py.edge[i].to,py.edge[i].fr);
        }
        for(int i=1;i<=n;i++) if(!L[i]) pn.DFS(i);
        for(int i=1;i<=n;i++) if(!pn.vis[i]) printf("%d
    ",i);
         
    //  pn.outE(n+m);
    //  cout<<"---"<<endl;
        pn.clr();
        memset(L,0,sizeof(L));
        for(int i=1;i<=cp;i++) L[pr[i].second]=pr[i].first;
        for(int i=1;i<2*k;i+=2) {
            if(L[py.edge[i].fr]!=py.edge[i].to) pn.AddEdge(py.edge[i].fr,py.edge[i].to);
            else pn.AddEdge(py.edge[i].to,py.edge[i].fr);
        }
        for(int i=1;i<=m;i++) if(!L[i+n]) pn.DFS(i+n);
        for(int i=1;i<=m;i++) if(!pn.vis[i+n]) printf("%d
    ",i);
    //  pn.outE(n+m);
        return 0;
    }
    

      

  • 相关阅读:
    获取华为OID
    win10 mongodb的安装
    第一次使用plotly画图遇到的问题
    Java Serialable序列化
    yield(),sleep(),join()
    线程的启动的两种方法,Runnable接口,run()的调用
    Thread的中断机制
    Oracle VM VirtualBox 修改备份位置
    潜在因子算法
    Linux--常用命令
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6784698.html
Copyright © 2011-2022 走看看