这题并不是太难

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

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

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

贴代码:

#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. docker学习(dockerfile打jar包为镜像)

    docker打包jar为docker镜像 1.使用Dockerfile打镜像 将spring boot应用打包成jar包放置在/app/applcation路径中 编写dockerfile文件,内容参 ...

  2. 当前我对Visual Grounding的看法

    3D Visual Grounding 在看到相关论文的时候,我有一种非常严重的直觉--我的博士课题大概就是做这个了,虽然还没找老师聊. 简要解释:在这个任务中,研究者的主要目标是探索如何利用图像和自 ...

  3. 了解了一下Cookie

    昨天做接口测试被Cookie折腾得云里雾里的,今天下午有时间特意了解了一下. 一:Edge浏览器查看Cookie的路径:设置->Cookie和网站权限 二:一个cookies包含以下信息:(1) ...

  4. Mybatis二级缓存(1)

  5. docker0 flannel.1不在同一网段

    现象: docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.2 ...

  6. 在windows 7下构建 FTP 服务器

    首先我们在C盘建立两个文件夹,用于发ftp的上传和下载 其次我们找到控制面板>程序>打开或关闭windows功能 进入后找到Internet 信息服务>FTP服务器>确定! 选 ...

  7. RepVGG:一个结构重参数化网络

    ​  本文来自公众号"AI大道理" ResNet.DenseNet 等复杂的多分支网络可以增强模型的表征能力,使得训练效果更好.但是多分支的结构在推理的时候效率严重不足. 看起来二 ...

  8. Docker学习笔记-02 常用命令

    1.启动类: 启动docker: systemctl start docker 停止docker: systemctl stop docker 重启docker: systemctl restart ...

  9. vue中v-if控制的可编辑div(contenteditable='true')无法绑定@input事件

    <div class="content-container" ref="contentContainer"> <div v-if=" ...

  10. eclipse的快捷键都有哪些

    非常实用的快捷键 Ctrl+D: 删除当前行 Ctrl+Alt+↓: 复制当前行到下一行 Ctrl+Alt+↑: 复制当前行到上一行 Alt+↓: 当前行和下面一行交互位置 Alt+↑: 当前行和上面 ...