这题并不是太难

首先题目我们将每个城市拆点,由源点向一端连容量为初始人数的边,由另一端向汇点连容量为最后人数的边,然后按照题目要求从一端向另一端连容量无穷大的边

这样跑出最大流之后我们只需比较这个流量与总人数是否相等就知道是否合法了

至于输出方案,一个点向另一个点的所有流量都会体现在反向边上,因此我们只需最后统计反向边即可

贴代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
const int inf=0x3f3f3f3f;
struct Edge
{
int nxt;
int to;
int val;
}edge[500005];
int head[5005];
int dis[5005];
int cur[5005];
int v0[5005],v1[5005];
int re[105][105];
int cnt=1;
int n,m;
int st,ed;
int sum1=0,sum2=0;
void add(int l,int r,int w)
{
edge[cnt].nxt=head[l];
edge[cnt].to=r;
edge[cnt].val=w;
head[l]=cnt++;
}
void dadd(int l,int r,int w)
{
add(l,r,w),add(r,l,0);
}
int ide(int x)
{
return x&1?x+1:x-1;
}
bool bfs()
{
memset(dis,0,sizeof(dis));
memcpy(cur,head,sizeof(head));
dis[st]=1;
queue <int> M;
M.push(st);
while(!M.empty())
{
int u=M.front();
M.pop();
for(int i=head[u];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(!dis[to]&&edge[i].val)dis[to]=dis[u]+1,M.push(to);
}
}
return dis[ed];
}
int dfs(int x,int lim)
{
if(x==ed)return lim;
int ret=0;
for(int i=cur[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(dis[to]==dis[x]+1&&edge[i].val)
{
int temp=dfs(to,min(lim,edge[i].val));
if(temp)
{
ret+=temp,lim-=temp;
edge[i].val-=temp,edge[ide(i)].val+=temp;
if(!lim)break;
}
}
}
return ret;
}
int dinic()
{
int ans=0;
while(bfs())ans+=dfs(st,inf);
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
st=2*n+1,ed=2*n+2;
for(int i=1;i<=n;i++)scanf("%d",&v0[i]),dadd(st,i,v0[i]),sum1+=v0[i];
for(int i=1;i<=n;i++)scanf("%d",&v1[i]),dadd(i+n,ed,v1[i]),sum2+=v1[i];
if(sum1!=sum2){printf("NO\n");return 0;}
for(int i=1;i<=n;i++)dadd(i,i+n,inf);
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
dadd(x,y+n,inf),dadd(y,x+n,inf);
}
int t=dinic();
if(t==sum1)
{
printf("YES\n");
for(int i=1;i<=n;i++)
{
for(int j=head[i];j;j=edge[j].nxt)
{
int to=edge[j].to;
if(to>n)re[i][to-n]=edge[ide(j)].val;
}
}
for(int i=1;i<=n;i++,printf("\n"))for(int j=1;j<=n;j++)printf("%d ",re[i][j]);
}else printf("NO\n");
return 0;
}

CF546E的更多相关文章

  1. CF546E Soldier and Traveling(网络流,最大流)

    CF546E Soldier and Traveling 题目描述 In the country there are \(n\) cities and \(m\) bidirectional road ...

  2. CF546E Soldier and Traveling

    题目描述 In the country there are n n n cities and m m m bidirectional roads between them. Each city has ...

  3. Codeforces Round #304 (Div. 2)(CF546E) Soldier and Traveling(最大流)

    题意 给定 n 个城市,m 条边.人只能从走相邻边相连(只能走一次)的城市. 现在给你初始城市的每一个人数,再给一组每个城市人数.询问是否可以从当前人数变换到给定人数.如果能,输入"YES& ...

随机推荐

  1. C# 生成二维码方法(QRCoder)

    前言 二维码很多地方都有使用到.如果是静态的二维码还是比较好处理的,通过在线工具就可以直接生成一张二维码图片,比如:草料二维码. 但有的时候是需要动态生成的(根据动态数据生成),这个使用在线就工具就无 ...

  2. unctfWP

    web: 签到:,更改学号,找规律,用笔记本记录出现的数据. 我太喜欢哔哩哔哩大学啦--中北大学:就往下面翻找flag,就会看见一个flag的语句,这个就是答案. ezgame-浙江师范大学:这个就是 ...

  3. spring mvc问题:源服务器未能找到目标资源的表示或者是不愿公开一个已经存在的资源表示

    HTTP状态 404 - 未找到 类型 状态报告 描述 源服务器未能找到目标资源的表示或者是不愿公开一个已经存在的资源表示. 我的问题:spring mvc无法访问到映射的controller,页面显 ...

  4. SQL Server修改表的时候出现错误:未更新任何行,未删除任何行

    无论点击什么,一直报错:未更新任何行,未删除任何行,就差点砸电脑啦. 参考这个大神才解决的问题: https://blog.csdn.net/weixin_44690047/article/detai ...

  5. nginx status code 状态码

    目录 1XX 临时响应并需要请求者继续执行操作的状态代码 2XX 成功功处理了请求的状态代码 3XX 重定向 要完成请求,需要进一步操作 通常用来重定向 4XX 表示请求可能出错,妨碍了服务器的处理 ...

  6. Spring不同版本的AOP

    1.Spring4.SpringBoot1 1.1 代码实现 public interface Calculator { int div(int a,int b); } @Component publ ...

  7. 【服务器数据恢复】Linux服务器分区不能挂载的数据恢复案例

    服务器数据恢复环境:某品牌PowerEdge系列服务器,磁盘阵列存储型号为该品牌MD3200系列存储,分配lun:linux centos 7操作系统,EXT4文件系统. 服务器故障:服务器在工作中由 ...

  8. -behaviour()的使用,他具体有什么作用

    Eralng 编程中的OTP OTP里面创建进程时 常用有四大behaviour • supervisor • gen_server • gen_fsm • gen_event 在erlang的编译器 ...

  9. Kotlin属性委托

    业务定义 对于属性,我们可以读取(get)和赋值(set),在Java中会定义get和set方法来操作属性,Kotlin的属性建议直接操作,一些业务的要求会对属性有额外的功能需求,在Java中会在ge ...

  10. git的基本操作(一)

    pwd: 显示当前所在的目录路径 ls: 列出当前目录的所有文件 touch: 新建一个文件 rm:删除一个文件 mkdir:新建一个目录 rm -r:删除一个目录 mv:移动一个文件到另一个文件中 ...