Time Limit: 2000MS | Memory Limit: 20000K | |
Total Submissions: 8259 | Accepted: 2306 |
Description
Input
Output
Sample Input
3 1 3 1 1 0 1 1 1 0 1 1
Sample Output
1 2
Source
枚举思路:
枚举一条边,并计算没有这条边的最大流,如最大流减少,则删去此边,记下此时的最大流,否则,不删边,枚举下一条边;这样反复枚举,计算,记录,直到最后最大流变为0.枚举结束,求得最小割的边。
#include<vector> #include<stdio.h> #include<queue> #include<string.h> using namespace std; #define INF 0x3f3f3f3f #define MAXN 5000 struct Edge{ int from,to,cap,flow; }; struct Dinic{ int n,m,s,t; vector<Edge> edges; vector<int> G[MAXN]; bool vis[MAXN]; int d[MAXN]; int cur[MAXN]; void init(int n){ this->n=n; for(int i=0;i<=n;i++)G[i].clear(); edges.clear(); } void AddEdge(int from,int to,int cap){ Edge e; e.from=from;e.to=to;e.cap=cap;e.flow=0; edges.push_back(e); e.from=from;e.to=to;e.cap=0;e.flow=0; edges.push_back(e); m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS(){ memset(vis,0,sizeof(vis)); queue<int> Q; Q.push(s); d[s]=0; vis[s]=1; while(!Q.empty()){ int x=Q.front(); Q.pop(); for(int i=0;i<(int)G[x].size();i++){ Edge& e=edges[G[x][i]]; if(!vis[e.to]&&e.cap>e.flow){ vis[e.to]=1; d[e.to]=d[x]+1; Q.push(e.to); } } } return vis[t]; } int DFS(int x,int a){ if(x==t||a==0)return a; int flow=0,f; for(int& i=cur[x];i<(int)G[x].size();i++){ Edge& e=edges[G[x][i]]; if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){ e.flow+=f; edges[G[x][i]^1].flow-=f; flow+=f; a-=f; if(a==0)break; } } return flow; } int Maxflow(int s,int t,int need){ this->s=s;this->t=t; int flow=0; while(BFS()){ memset(cur,0,sizeof(cur)); flow+=DFS(s,INF); if(flow>need)return flow; } return flow; } //最小割割边 vector<int> Mincut(){ BFS(); vector<int> ans; for(int i=0;i<(int)edges.size();i++){ Edge& e=edges[i]; if(vis[e.from]&&!vis[e.to]&&e.cap>0)ans.push_back(i); } return ans; } void Reduce(){ for(int i = 0; i <(int)edges.size(); i++) edges[i].cap -= edges[i].flow; } void ClearFlow(){ for(int i = 0; i <(int)edges.size(); i++) edges[i].flow = 0; } }; Dinic g; int map[222][222],Erase[222]; int getflow(int n,int src,int des) { int i; g.init(2*n); src=src+n; for(i=1;i<=n;i++) if(!Erase[i]) g.AddEdge(i,i+n,1); else g.AddEdge(i,i+n,0); for(i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==j) continue; if(map[i][j]==1) g.AddEdge(i+n,j,INF); } } return g.Maxflow(src,des,INF); } int main() { int n,i,j,src,des; while(scanf("%d %d %d",&n,&src,&des)!=EOF) { memset(Erase,0,sizeof(Erase)); memset(map,0,sizeof(map)); for(i=1;i<=n;i++) for(j=1;j<=n;j++) scanf("%d",&map[i][j]); int maxflow=getflow(n,src,des); if(map[src][des]) {printf("NO ANSWER!\n");continue;} else printf("%d\n",maxflow); vector<int>ans; for(i=1;i<=n;i++) { if(i==src||i==des) continue; Erase[i]=1; int flow=getflow(n,src,des); if(flow<maxflow) { ans.push_back(i); maxflow=flow; } else Erase[i]=0; if(maxflow<=0) break; } int cnt=ans.size(); if(cnt==0) continue; for(i=0;i<cnt-1;i++) printf("%d ",ans[i]); printf("%d\n",ans[i]); } return 0; }