LA3231 Fair Share 二分_网络流
Code:
#include<cstdio> #include<vector> #include<queue> #include<cstring> #include<algorithm> using namespace std; const int maxn=50004; const int INF=10000000; # define pb push_back int N,M; int s,t; struct Edge{ int from,to,cap; Edge(int u,int v,int c):from(u),to(v),cap(c) {} }; struct Dicnic{ vector<Edge>edges; vector<int>G[maxn]; int d[maxn],vis[maxn],cur[maxn]; queue<int>Q; void init(){ for(int i=0;i<maxn;++i)G[i].clear(); edges.clear(); } void addedge(int u,int v,int c){ edges.pb(Edge(u,v,c)); //正向弧 edges.pb(Edge(v,u,0)); //反向弧 int m=edges.size(); G[u].pb(m-2); G[v].pb(m-1); } int BFS() { memset(vis,0,sizeof(vis)); d[s]=0,vis[s]=1;Q.push(s); while(!Q.empty()){ int u=Q.front();Q.pop(); int sz=G[u].size(); for(int i=0;i<sz;++i){ Edge e=edges[G[u][i]]; if(!vis[e.to]&&e.cap>0){ d[e.to]=d[u]+1,vis[e.to]=1; Q.push(e.to); } } } return vis[t]; } int dfs(int x,int a){ if(x==t)return a; int sz=G[x].size(); int f,flow=0; for(int i=cur[x];i<sz;++i){ Edge e=edges[G[x][i]]; cur[x]=i; if(d[e.to]==d[x]+1&&e.cap>0){ f=dfs(e.to,min(a,e.cap)); if(f) { int u=G[x][i]; a-=f; edges[u].cap-=f; edges[u^1].cap+=f; flow+=f; if(a==0)break; } } } return flow; } int maxflow(){ int ans=0; while(BFS()){ memset(cur,0,sizeof(cur)); ans+=dfs(s,INF); } return ans; } int check(int x) { int siz=G[0].size(); for(int i=0;i<siz;++i)edges[G[s][i]].cap=1,edges[G[s][i]^1].cap=0; for(int i=1;i<=M;++i) { int sz=G[i].size(); for(int j=0;j<sz;++j) { int v=edges[G[i][j]].to; if(v!=s){ edges[G[i][j]].cap=1,edges[G[i][j]^1].cap=0; } } } for(int i=M+1;i<=N+M;++i) { int sz=G[i].size(); for(int j=0;j<sz;++j) { int v=edges[G[i][j]].to; if(v==t){ edges[G[i][j]].cap=x,edges[G[i][j]^1].cap=0; } } } int uu=maxflow(); if(uu==M)return 1; return 0; } int operate() { int L=0,R=12000; int fin=0; while(L<=R) { int mid=(L+R)/2; if(check(mid)){fin=mid,R=mid-1;} else L=mid+1; } return fin; } }op; int main() { //freopen("in.txt","r",stdin); int T; scanf("%d",&T); while(T--) { op.init(); scanf("%d%d",&N,&M); s=0,t=N+M+1; for(int i=1;i<=M;++i)op.addedge(s,i,1); for(int i=1;i<=M;++i){ int a,b; scanf("%d%d",&a,&b); a+=M,b+=M; op.addedge(i,a,1); op.addedge(i,b,1); } for(int i=M+1;i<=N+M;++i)op.addedge(i,t,0); printf("%d\n",op.operate()); } return 0; }