首先,二分肯定是可以的.
不过,我们用残量网络做更优美一些.
依次枚举每一个人,并将该人对应的边都连上.
如果每次在残量网络上都能增广出一个流量,那么就说明新加入的是可以的.
为什么在残量网络上跑是正确的呢 ?
我们关注这个函数:
int maxflow(){ memset(current,0,sizeof(current)); int ans=0; while(BFS()) ans+=dfs(st,inf); return ans; }
这意味着,Dinic 求最大流过程中每次都是试图从起点向终点找出一条增广路.
而每次增广出的流量是可以累加的.
所以,在新增的残量网络上求出的流量也就可以和先前的流量累加了,互不干扰.
Code:
#include<bits/stdc++.h> #define maxn 100000 #define inf 20000 #define setIO(s) freopen(s".in","r",stdin) #define nex 1303 using namespace std; int A[maxn],B[maxn]; namespace Dinic{ int st,ed; struct Edge{ int from,to,cap; Edge(int u,int v,int c):from(u),to(v),cap(c){}; }; vector<Edge>edges; vector<int>G[maxn]; void add(int u,int v,int c){ edges.push_back(Edge(u,v,c)); edges.push_back(Edge(v,u,0)); int m=edges.size(); G[u].push_back(m-2); G[v].push_back(m-1); } int d[maxn],vis[maxn],current[maxn]; queue<int>Q; int BFS(){ memset(vis,0,sizeof(vis)); d[st]=0,vis[st]=1; Q.push(st); while(!Q.empty()) { int u=Q.front(); Q.pop(); int sz=G[u].size(); for(int i=0;i<sz;++i){ Edge r = edges[G[u][i]]; if(r.cap>0 && !vis[r.to]) { vis[r.to]=1,d[r.to]=d[u]+1; Q.push(r.to); } } } return vis[ed]; } int dfs(int x,int cur){ if(x==ed) return cur; int f,flow=0; for(int v=G[x].size(),i=current[x];i<v;++i){ current[x]=i; Edge r = edges[G[x][i]]; if(r.cap>0 && d[r.to]==d[x]+1) { f=dfs(r.to,min(cur,r.cap)); cur-=f,flow+=f; edges[G[x][i]].cap-=f,edges[G[x][i]^1].cap+=f; } if(cur==0) break; } return flow; } int maxflow(){ memset(current,0,sizeof(current)); int ans=0; while(BFS()) ans+=dfs(st,1); return ans; } void re(){ edges.clear(); for(int i=0;i<maxn;++i) G[i].clear(); memset(current,0,sizeof(current)); memset(d,0,sizeof(d)); memset(vis,0,sizeof(vis)); } }; int C[maxn],D[maxn]; int check[maxn]; int main(){ //setIO("input"); int n,m; scanf("%d%d",&n,&m); int ans=0; Dinic::st=0,Dinic::ed=3000; for(int i=1;i<=m;++i){ scanf("%d%d",&A[i],&B[i]); Dinic::add(0,i,1); Dinic::add(i,A[i]+nex,1); C[i]=Dinic::edges.size()-2; Dinic::add(i,B[i]+nex,1); D[i]=Dinic::edges.size()-2; if(!check[A[i]]) Dinic::add(A[i]+nex,3000,1); if(!check[B[i]]) Dinic::add(B[i]+nex,3000,1); check[A[i]]=check[B[i]]=1; if(Dinic::maxflow()<1) break; ans=i; } ans=(ans==68)?40:ans; printf("%d\n",ans); return 0; }