您的位置:首页 > 理论基础 > 计算机网络

Codeforces Round #304 (Div. 2)E. Soldier and Traveling 网络流

2016-02-24 21:12 531 查看
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1442

题意:n个城市,m条边, 每个点刚开始有ai个人,问最后能不能有bi个人,每个城市的人,要么不走,要么只能走到相邻的城市

输出能否达到并输出转移方案!

思路:最大流 s-a[i]-b[i]-t建图

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=5000;
const int  INF=1000000000;
int N,M;
int A[maxn],B[maxn];
int tot,head[maxn];
int st,en,nn,cur[maxn];
int ans[maxn][maxn];
int dis[maxn],gap[maxn],vis[maxn],pre[maxn];
struct node
{
int v,next,f,flow;
}edge[maxn*4];
void init()
{
tot=0;
memset(head,-1,sizeof(head));
}
void add_edge(int x,int y,int f)
{
edge[tot].v=y;
edge[tot].f=f;
edge[tot].flow=0;
edge[tot].next=head[x];
head[x]=tot++;
edge[tot].v=x;
edge[tot].f=0;
edge[tot].flow=0;
edge[tot].next=head[y];
head[y]=tot++;
}
int SAP(int st,int en)
{
for(int i=0;i<=nn;i++)
{
cur[i]=head[i];
dis[i]=gap[i]=0;
}
int u=0;
int flow=0,aug=INF;
gap[st]=nn;
u=pre[st]=st;
bool flag;
while(dis[st]<nn)
{
flag=0;
for(int &j=cur[u];j!=-1;j=edge[j].next)
{
int v=edge[j].v;
if(edge[j].f>0&&dis[u]==dis[v]+1)
{
flag=1;
if(edge[j].f<aug)aug=edge[j].f;
pre[v]=u;
u=v;
if(u==en)
{
flow+=aug;
while(u!=st)
{
u=pre[u];
edge[cur[u]].f-=aug;
edge[cur[u]].flow-=aug;
edge[cur[u]^1].f+=aug;
edge[cur[u]^1].flow+=aug;
}
aug=INF;
}
break;
}
}

if(flag)continue;
int mindis=nn;
for(int j=head[u];j!=-1;j=edge[j].next)
{
int v=edge[j].v;
if(dis[v]<mindis&&edge[j].f>0)
{
mindis=dis[v];
cur[u]=j;
}
}
if((--gap[dis[u]])==0)break;
gap[dis[u]=mindis+1]++;
u=pre[u];
}
return flow;
}
int main()
{
scanf("%d%d",&N,&M);
st=0,en=2*N+1,nn=en+1;
init();
int sum=0,sum1=0;
for(int i=1;i<=N;i++)
{
scanf("%d",&A[i]);
sum+=A[i];
add_edge(st,i,A[i]);
}
for(int i=1;i<=N;i++)
{
scanf("%d",&B[i]);
sum1+=B[i];
add_edge(i,i+N,INF);
add_edge(i+N,en,B[i]);
}
while(M--)
{
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v+N,INF);
add_edge(v,u+N,INF);
}

if(sum!=sum1){printf("NO\n");return 0;}
int flow=SAP(st,en);
if(flow!=sum){printf("NO\n");}
else
{
for(int i=1;i<=N;i++)
for(int j=head[i];j!=-1;j=edge[j].next)
{
int v=edge[j].v;
ans[i][v-N]=-edge[j].flow;
}
printf("YES\n");
for(int i=1;i<=N;i++)
{
for(int j=1;j<=N;j++)
printf("%d ",ans[i][j]);
printf("\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces 51nod