标签:mat bin aws scanf raw character int assign while
Time Limit: 2000MS | Memory Limit: 65536K | |||
Total Submissions: 8503 | Accepted: 2753 | Special Judge |
Description
Input
Output
Sample Input
3 6 1 2 3 4 2 1 1 2 1 1 3 2 1 2 3 1 2 3
Sample Output
5 3 1 + 2 - 2 +
主要是找割边。
有构造出来的图知道这个是个二部图加两个源点汇点,二部图之间的连边不可能是割边(INF),所以就dfs(S)然后用vis标记,那么vis[S]一定是1,并且vis[T]一定是0.因为S,T不可能在一个集合里
那么从源点处找一下和它相连的边,看vis[]是不是0,是的话就是割边。
然后从汇点处找一下和它相连的边,看vis[]是不是1,是的话就是割边。
因为是个二部图所以不用dfs直接找一次就可以了
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int N=280; const int M=5888; const int INF=1e9+7; int head[N],tot,S,T; int q[N],dis[N],n,m,Q; bool vis[N]; struct node { int next,v,w; } e[M<<2]; void add(int u,int v,int w) { e[tot].v=v; e[tot].w=w; e[tot].next=head[u]; head[u]=tot++; } bool bfs() { memset(dis,-1,sizeof(dis)); dis[S]=0; int l=0,r=0; q[r++]=S; while(l<r) { int u=q[l++]; for(int i=head[u]; ~i; i=e[i].next) { int v=e[i].v; if(dis[v]==-1&&e[i].w>0) { q[r++]=v; dis[v]=dis[u]+1; if(v==T) return true; } } } return false; } int dfs(int s,int low) { if(s==T||!low) return low; int ans=low,a; for(int i=head[s]; ~i; i=e[i].next) { if(e[i].w>0&&dis[e[i].v]==dis[s]+1&&(a=dfs(e[i].v,min(e[i].w,ans)))) { e[i].w-=a; e[i^1].w+=a; ans-=a; if(!ans) return low; } } if(low==ans) dis[s]=-1; return low-ans; } void dfs(int u){ vis[u]=1; for(int i=head[u];~i;i=e[i].next) if(!vis[e[i].v]&&e[i].w) dfs(e[i].v); } int a[N],b[N]; int main() { while(scanf("%d%d",&n,&m)!=EOF) { S=0,T=2*n+1; int x,f,t; memset(head,-1,sizeof(head)); tot=0; for(int i=1; i<=n; ++i) { scanf("%d",&x); add(S,i,x); add(i,S,0); } for(int i=1; i<=n; ++i) { scanf("%d",&x); add(i+n,T,x); add(T,i+n,0); } while(m--) { scanf("%d%d",&f,&t); add(t,f+n,INF); add(f+n,t,0); } int ans=0; while(bfs()) ans+=dfs(S,INF); printf("%d\n",ans); dfs(S); int ct1=0,ct2=0; for(int i=head[S];~i;i=e[i].next) if(!vis[e[i].v]) a[ct1++]=e[i].v; for(int i=head[T];~i;i=e[i].next) if(vis[e[i].v]) b[ct2++]=e[i].v-n; printf("%d\n",ct1+ct2); for(int i=0;i<ct1;++i) printf("%d +\n",a[i]); for(int i=0;i<ct2;++i) printf("%d -\n",b[i]); } }
标签:mat bin aws scanf raw character int assign while
原文地址:http://www.cnblogs.com/mfys/p/7493664.html