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

来源:互联网 发布:怎么制作淘宝店铺模板 编辑:程序博客网 时间:2024/06/06 03:36

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;}
1 0
原创粉丝点击