BZOJ 3546: [ONTAK2010]Life of the Party
Posted 北屿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 3545ONTAK 2010Peaks & BZOJ 3551ONTAK 2010Peaks加强版 Kruskal重构树
bzoj3545/bzoj3551 [ONTAK2010]Peaks/Peaks加强版
BZOJ3544[ONTAK2010]Creative Accounting 前缀和+set