Time Limit: 2000MS | Memory Limit: 20000K | |
Total Submissions: 8640 | Accepted: 2412 |
Description
Input
Output
Sample Input
3 1 3 1 1 0 1 1 1 0 1 1
Sample Output
1 2
题意:给定一个图,求去掉最少的顶点,使得s与t不连通,答案有多个时,按输出字典序最小的。
假如s与t直接连通,则无解,
否则拆点,一个点拆成入度,出度两个点,之间s,t两个点流量为无穷大,其他点为1,然后建图,跑一遍最大流,
然后从小到大枚举除s,t之外的点,用一个数组标记把点去掉,建图跑最大流,假如流量减少,则说明这个点需要去掉,否则这个点无关紧要,不能去掉,
然后输出答案即可。
代码:
/* *********************************************** Author :rabbit Created Time :2014/3/8 16:40:10 File Name :1718.cpp ************************************************ */ #pragma comment(linker, "/STACK:102400000,102400000") #include <stdio.h> #include <iostream> #include <algorithm> #include <sstream> #include <stdlib.h> #include <string.h> #include <limits.h> #include <string> #include <time.h> #include <math.h> #include <queue> #include <stack> #include <set> #include <map> using namespace std; #define INF 0x3f3f3f3f #define eps 1e-8 #define pi acos(-1.0) typedef long long ll; const int maxn=1010; const int maxm=400010; struct Edge{ int to,next,cap,flow; Edge(){}; Edge(int _next,int _to,int _cap,int _flow){ next=_next;to=_to;cap=_cap;flow=_flow; } }edge[maxm]; int head[maxn],tol,gap[maxn],dep[maxn],cur[maxn]; void addedge(int u,int v,int flow){ edge[tol]=Edge(head[u],v,flow,0);head[u]=tol++; edge[tol]=Edge(head[v],u,0,0);head[v]=tol++; } int Q[maxn]; void bfs(int start,int end){ memset(dep,-1,sizeof(dep)); memset(gap,0,sizeof(gap)); gap[0]++;int front=0,rear=0; dep[end]=0;Q[rear++]=end; while(front!=rear){ int u=Q[front++]; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to;if(dep[v]==-1&&edge[i].cap) Q[rear++]=v,dep[v]=dep[u]+1,gap[dep[v]]++; } } } int S[maxn]; int sap(int start,int end,int N){ bfs(start,end); memcpy(cur,head,sizeof(head)); int top=0,u=start,ans=0; while(dep[start]<N){ if(u==end){ int MIN=INF,id; for(int i=0;i<top;i++) if(MIN>edge[S[i]].cap-edge[S[i]].flow) MIN=edge[S[i]].cap-edge[S[i]].flow,id=i; for(int i=0;i<top;i++) edge[S[i]].flow+=MIN,edge[S[i]^1].flow-=MIN; ans+=MIN,top=id,u=edge[S[top]^1].to; continue; } bool flag=0;int v; for(int i=cur[u];i!=-1;i=edge[i].next){ v=edge[i].to; if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u]){ flag=1;cur[u]=i;break; } } if(flag){ S[top++]=cur[u];u=v;continue; } int MIN=N; for(int i=head[u];i!=-1;i=edge[i].next) if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<MIN) MIN=dep[edge[i].to],cur[u]=i; if(--gap[dep[u]]==0)break;gap[dep[u]=MIN+1]++; if(u!=start)u=edge[S[--top]^1].to; } return ans; } int flag[400][400],mark[500]; int main() { //freopen("data.in","r",stdin); //freopen("data.out","w",stdout); int n,s,t; while(~scanf("%d%d%d",&n,&s,&t)){ memset(head,-1,sizeof(head));tol=0; memset(mark,0,sizeof(mark)); for(int i=1;i<=n;i++){ if(i==s||i==t)addedge(i,i+n,INF); else addedge(i,i+n,1); for(int j=1;j<=n;j++){ scanf("%d",&flag[i][j]); if(flag[i][j]&&i!=j) addedge(i+n,j,INF); } } if(flag[s][t]){ printf("NO ANSWER!\n"); continue; } vector<int> ans; addedge(0,s,INF);addedge(t+n,2*n+1,INF); int pre=sap(0,2*n+1,4*n+10); for(int i=1;i<=n;i++){ if(i==s||i==t)continue; mark[i]=1; memset(head,-1,sizeof(head));tol=0; for(int j=1;j<=n;j++){ if(mark[j])continue; if(j!=s&&j!=t)addedge(j,j+n,1); else addedge(j,j+n,INF); } for(int j=1;j<=n;j++){ for(int k=1;k<=n;k++){ if(flag[j][k]&&k!=j&&!mark[j]&&!mark[k]) addedge(j+n,k,INF); } } addedge(0,s,INF);addedge(t+n,2*n+1,INF); int ret=sap(0,2*n+1,4*n+10); if(ret<pre)ans.push_back(i),pre=ret; else mark[i]=0; } printf("%d\n",ans.size()); if(ans.size()){ for(int i=0;i<ans.size();i++) printf("%d%c",ans[i],i==ans.size()-1?‘\n‘:‘ ‘); } } return 0; }
原文:http://blog.csdn.net/xianxingwuguan1/article/details/20792079