首页 > 代码库 > BZOJ 3546: [ONTAK2010]Life of the Party

BZOJ 3546: [ONTAK2010]Life of the Party

Description

一个二分图最大匹配,求出所有关键点.\(n,m\leqslant 10^4,k\leqslant 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\n",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\n",i);//  pn.outE(n+m);    return 0;}

  

BZOJ 3546: [ONTAK2010]Life of the Party