CF546E Soldier and Traveling

题目描述

In the country there are n n n cities and m m m bidirectional roads between them. Each city has an army. Army of the i i i -th city consists of ai a_{i} ai? soldiers. Now soldiers roam. After roaming each soldier has to either stay in his city or to go to the one of neighboring cities by at moving along at most one road.

Check if is it possible that after roaming there will be exactly bi b_{i} bi? soldiers in the i i i -th city.

输入输出格式

输入格式:

First line of input consists of two integers n n n and m m m ( 1<=n<=100 1<=n<=100 1<=n<=100 , 0<=m<=200 0<=m<=200 0<=m<=200 ).

Next line contains n n n integers a1,a2,...,an a_{1},a_{2},...,a_{n} a1?,a2?,...,an? ( 0<=ai<=100 0<=a_{i}<=100 0<=ai?<=100 ).

Next line contains n n n integers b1,b2,...,bn b_{1},b_{2},...,b_{n} b1?,b2?,...,bn? ( 0<=bi<=100 0<=b_{i}<=100 0<=bi?<=100 ).

Then m m m lines follow, each of them consists of two integers p p p and q q q ( 1<=p,q<=n 1<=p,q<=n 1<=p,q<=n , p≠q p≠q p≠q ) denoting that there is an undirected road between cities p p p and q q q .

It is guaranteed that there is at most one road between each pair of cities.

输出格式:

If the conditions can not be met output single word "NO".

Otherwise output word "YES" and then n n n lines, each of them consisting of n n n integers. Number in the i i i -th line in the j j j -th column should denote how many soldiers should road from city i i i to city j j j (if i≠j i≠j i≠j ) or how many soldiers should stay in city i i i (if i=j i=j i=j ).

If there are several possible answers you may output any of them.

输入输出样例

输入样例#1:

4 4
1 2 6 3
3 5 3 1
1 2
2 3
3 4
4 2

输出样例#1:

YES
1 0 0 0
2 0 0 0
0 5 1 0
0 0 2 1

输入样例#2:

2 0
1 2
2 1

输出样例#2:

NO

Solution:

  本题最大流,建图贼有意思。

  题意就是给定一些点上的初始士兵数,问能否通过相邻间的互相移动(只能邻边之间移动一次),达到每个点的目标士兵数。

  首先我们可以特判出一个非法情况:$\sum\limits_{i=1}^{i\leq n}{a_i}\neq\sum\limits_{i=1}^{i\leq n}{b_i}$直接无解。

  然后网络流的建图比较常规,源点$s\rightarrow i$边权为$a_i$,$i\rightarrow j$($i==j$或者$i$与$j$相邻)边权为$inf$,$j\rightarrow t$边权为$b_j$。跑出最大流后,判断总流量是否等于$a$的和,输出方案只要扫下中间连的反向边就好了。

代码:

 1 #include<bits/stdc++.h>
 2 #define il inline
 3 #define ll long long
 4 #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
 5 #define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
 6 #define debug printf("%d %s\n",__LINE__,__FUNCTION__)
 7 using namespace std;
 8 const int N=505,M=200005,inf=233333333;
 9 int n,m,s,t=250,a[N],b[N],to[M],net[M],w[M],cnt=1,h[N],dis[N];
10 int mp[N][N];
11 bool f;
12
13 il int gi(){
14     int a=0;char x=getchar();bool f=0;
15     while((x<‘0‘||x>‘9‘)&&x!=‘-‘)x=getchar();
16     if(x==‘-‘)x=getchar(),f=1;
17     while(x>=‘0‘&&x<=‘9‘)a=(a<<3)+(a<<1)+x-48,x=getchar();
18     return f?-a:a;
19 }
20
21 il void add(int u,int v,int c){to[++cnt]=v,net[cnt]=h[u],w[cnt]=c,h[u]=cnt;}
22
23 il bool bfs(){
24     queue<int>q;
25     memset(dis,-1,sizeof(dis));
26     q.push(s),dis[s]=0;
27     while(!q.empty()){
28         int u=q.front();q.pop();
29         for(int i=h[u];i;i=net[i])
30             if(dis[to[i]]==-1&&w[i])dis[to[i]]=dis[u]+1,q.push(to[i]);
31     }
32     return dis[t]!=-1;
33 }
34
35 il int dfs(int u,int op){
36     if(u==t)return op;
37     int flow=0,used=0;
38     for(int i=h[u];i;i=net[i]){
39         int v=to[i];
40         if(dis[v]==dis[u]+1&&w[i]>0){
41             used=dfs(v,min(w[i],op));
42             if(!used)continue;
43             flow+=used,op-=used;
44             w[i]-=used,w[i^1]+=used;
45             if(!op)break;
46         }
47     }
48     if(!flow)dis[u]=-1;
49     return flow;
50 }
51
52 il void init(){
53     n=gi(),m=gi();
54     For(i,1,n) a[i]=gi(),add(s,i,a[i]),add(i,s,0); For(i,1,n) b[i]=gi(),add(i+n,t,b[i]),add(t,i+n,0);
55     int u,v,c;
56     For(i,1,m) u=gi(),v=gi(),add(u,v+n,inf),add(v+n,u,0),add(v,u+n,inf),add(u+n,v,0);
57     For(i,1,n) add(i,i+n,inf),add(i+n,i,0);
58 }
59
60 il void solve(){
61     init();
62     int ans=0,ta=0,tb=0;
63     For(i,1,n) ta+=a[i],tb+=b[i];
64     if(ta!=tb) puts("NO");
65     else {
66         while(bfs())ans+=dfs(s,inf);
67         if(ans!=ta)puts("NO");
68         else {
69             puts("YES");
70             For(u,1,n) {
71                 for(int i=h[u+n];i;i=net[i])
72                     if(w[i]!=inf&&to[i]!=t) mp[to[i]][u]=w[i];
73             }
74             For(i,1,n) {For(j,1,n) printf("%d ",mp[i][j]); printf("\n");}
75         }
76     }
77 }
78
79 int main(){
80     solve();
81     return 0;
82 }

题目描述

In the country there are n n n cities and m m m bidirectional roads between them. Each city has an army. Army of the i i i -th city consists of ai a_{i} ai?
soldiers. Now soldiers roam. After roaming each soldier has to either
stay in his city or to go to the one of neighboring cities by at moving
along at most one road.

Check if is it possible that after roaming there will be exactly bi b_{i} bi? soldiers in the i i i -th city.

输入输出格式

输入格式:

First line of input consists of two integers n n n and m m m ( 1<=n<=100 1<=n<=100 1<=n<=100 , 0<=m<=200 0<=m<=200 0<=m<=200 ).

Next line contains n n n integers a1,a2,...,an a_{1},a_{2},...,a_{n} a1?,a2?,...,an? ( 0<=ai<=100 0<=a_{i}<=100 0<=ai?<=100 ).

Next line contains n n n integers b1,b2,...,bn b_{1},b_{2},...,b_{n} b1?,b2?,...,bn? ( 0<=bi<=100 0<=b_{i}<=100 0<=bi?<=100 ).

Then m m m lines follow, each of them consists of two integers p p p and q q q ( 1<=p,q<=n 1<=p,q<=n 1<=p,q<=n , p≠q p≠q p≠q ) denoting that there is an undirected road between cities p p p and q q q .

It is guaranteed that there is at most one road between each pair of cities.

输出格式:

If the conditions can not be met output single word "NO".

Otherwise output word "YES" and then n n n lines, each of them consisting of n n n integers. Number in the i i i -th line in the j j j -th column should denote how many soldiers should road from city i i i to city j j j (if i≠j i≠j i≠j ) or how many soldiers should stay in city i i i (if i=j i=j i=j ).

If there are several possible answers you may output any of them.

输入输出样例

输入样例#1:
复制

4 4
1 2 6 3
3 5 3 1
1 2
2 3
3 4
4 2

输出样例#1: 复制

YES
1 0 0 0
2 0 0 0
0 5 1 0
0 0 2 1

输入样例#2: 复制

2 0
1 2
2 1

输出样例#2: 复制

NO

原文地址:https://www.cnblogs.com/five20/p/9356571.html

时间: 2024-10-11 16:09:29

CF546E Soldier and Traveling的相关文章

Codeforces Round #304 (Div. 2) E. Soldier and Traveling 最大流 Dinic EK 算法

E. Soldier and Traveling time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output In the country there are n cities and m bidirectional roads between them. Each city has an army. Army of the i-th ci

网络流(最大流) CodeForces 546E:Soldier and Traveling

In the country there are n cities and m bidirectional roads between them. Each city has an army. Army of the i-th city consists of ai soldiers. Now soldiers roam. After roaming each soldier has to either stay in his city or to go to the one of neighb

Codeforces 546E Soldier and Traveling(最大流)

题目大概说一张无向图,各个结点初始有ai人,现在每个人可以选择停留在原地或者移动到相邻的结点,问能否使各个结点的人数变为bi人. 如此建容量网络: 图上各个结点拆成两点i.i' 源点向i点连容量ai的边 i'向汇点连容量bi的边 i向i'连容量INF的边 对于相邻的两点(u,v),u向v'连容量INF的边,v'向u连容量INF的边 跑最大流看看最大流是否等于∑bi.另外,注意∑ai不等于∑bi的情况. 1 #include<cstdio> 2 #include<cstring> 3

CodeForces 546E - Soldier and Traveling(最大流+输出边流量)

题目链接:click here~~ [题目大意]:给定一些城市里面原先状态的士兵数目,和某些城市之间的联通关系,求能否达到最终状态. [解题思路]做完这套题,感觉这道题是五个题里最有质量的题了,搞了差不多一天半的时间,开始很难想到构图,想到了是最大流之后,又卡在了输出流量上,w(?Д?)w,还是这类题做的太少,~~~~(>_<)~~~~!首先比较很难构想到最大流,但是抓住题目关键,仔细想想也不难,好,想到了是构造最大流,那么接下来难点是建源点,汇点,剩下的就是套模板了,弱弱的献上代码,欢迎各位

codeforces 546E. Soldier and Traveling 网络流

题目链接 给出n个城市, 以及初始时每个城市的人数以及目标人数.初始时有些城市是相连的. 每个城市的人只可以待在自己的城市或走到与他相邻的城市, 相邻, 相当于只能走一条路. 如果目标状态不可达, 输出no, 否则输出每个城市的人都是怎么走的, 比如第一个城市有2个人走到了第二个城市, 1个人留在了第一个城市, 那么输出的第一行前两个数就是1, 2. 很明显的网络流, 输出那里写了好久... 首先判断能否可达, 如果初始状态的人数与目标状态不一样, 一定不可达, 其次, 如果建完图跑网络流的结果

【CF】304 E. Soldier and Traveling

基础网络流,增加s和t,同时对于每个结点分裂为流入结点和流出结点.EK求最大流,判断最大流是否等于当前总人数. 1 /* 304E */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include

codeforces 546 E Soldier and Traveling

传送门 题意:给你初始状态和目标状态,再给你m条路,士兵只能通过路走到相邻城市去,一个士兵只能移动一次.问你能否到达该状态,如果能输出转移的矩阵 题解:很显然的网络流,将一个点拆成三个,一个初始状态与s连,一个目标状态与t连,容量b[i],在建立一个中间点,连接初始状态容量INF和目标状态容量a[i]:记录下每个中间点和相邻点的边,再跑完网络流后,原容量减去残余流量就能得到转移的士兵个数 #include <iostream> #include <cstdio> #include

Codeforce 水题报告(2)

又水了一发Codeforce ,这次继续发发题解顺便给自己PKUSC攒攒人品吧 CodeForces 438C:The Child and Polygon: 描述:给出一个多边形,求三角剖分的方案数(n<=200). 首先很明显可能是区间dp,我们可以记f[i][j]为从i到j的这个多边形的三角剖分数,那么f[i][j]=f[i][k]*f[j][k]*(i,j,k是否为1个合格的三角形) CodeForces 438D:The Child and Sequence 描述:给一个序列,要求支持区

Codeforces Round #304 (Div. 2) -----CF546

A. Soldier and Bananas A soldier wants to buy w bananas in the shop. He has to pay k dollars for the first banana, 2k dollars for the second one and so on (in other words, he has to pay i·k dollars for the i-th banana). He has n dollars. How many dol