这题并不是太难

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

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

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

贴代码:

#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. PyQt5模块说明

    pyqt5的类别分为几个模块,包括以下: QtCoreQtGuiQtWidgetsQtMultimediaQtBluetoothQtNetworkQtPositioningEnginioQtWebSo ...

  2. redis缓存一致性

    redis缓存一致性 redis是目前使用最广泛的分布式缓存系统,几乎每家公司都在用.它使用简单,吞吐量高,单机 qps 可以达到 10 万每秒,但在使用redis缓存时存在一个问题,即如何保证缓存数 ...

  3. ES实战-桶查询

    目的 研究聚合查询的BUCKETS桶·到底是如何计算? PS:es版本为7.8.1 Bucket概念 关于es聚合查询,官方介绍,可以参考 es聚合查询-bucket. 有道翻译: 桶聚合不像指标聚合 ...

  4. Linux中 cat查询文件指定内容-并输入到指定文件内

    常用: ① cat xxx.log | grep -C 20 "查询关键字" ② grep -E '1805|1905' CloudPayment.log > out.log ...

  5. BAPI_GOODSMVT_CREATE - 101 mvt. Message ERROR M7427

    Message SAP M7427 - Entered batch &1 does not match batch &2 in the purchase order 639934 - ...

  6. 配置代码片段问题 Invalid characters in string. Control characters must be escaped.

    在使用代码片段时报错 Invalid characters in string. Control characters must be escaped. " somethings" ...

  7. 实验1task3

    <实验结论> #include <stdio.h> #include <stdlib.h> int main() { int a, b, t; a = 3; b = ...

  8. yolov5s yolov8n 在自己数据集上测试比较(640*640)

    yolov5s -> 0.5map:  96.5 -> ncnn:75ms yolov8n -> 0.5map:  94.1 -> ncnn:52ms

  9. CAD专用卸载工具,完美彻底卸载清除干净cad各种残留注册表和文件。

    CAD专用卸载工具,完美彻底卸载清除干净cad各种残留注册表和文件.有的同学由于一些原因想把cad卸载掉然后重新安装,但是cad安装到一半就失败了或者显示已安装或者未完成,还有的同学会遇到" ...

  10. java面试准备基础篇

    1.Java中常用关键字和用途 synchronized: 加锁 transient 不参与序列化和反序列化 volatile 保证其他线程可见性,不保证原子性,禁止指令重排 2.hashCode() ...