题意 (CodeForces 546E)

对一个无向图,给出图的情况与各个节点的人数/目标人数。每个节点的人只可以待在自己的城市或走到与他相邻的节点。
问最后是否有解,输出一可行解(我以为是必须和答案一样,然后本机调了半天死活不一样,交上去结果A了- -)。

分析

典型的网络流。问题在于建模。如何解决两个节点的人数->目标人数?
考虑到我们始终要和这两个状态打交道,不妨将每个结点拆成两个(转移前&转移后),这两个点间的流量是INF。如果两点相连(不妨设为u,u',v,v'),那么uu与v′v′、vv与u′u′分别有流量为INF的边。
转移前的点连接一个源点,其间的边流量为它们的人数,转移后的点连接一个汇点,边流量同理。
建模完后跑一遍最大流就有结果了,如果汇点没有那么多人那么无解,反之有解。
接下来的问题是如何求移动的人数。还记得增广路怎么求的吗?(紫书p367)其中,反向边的流量就是移动的具体数目。这样,我们就能够得出具体的移动方法了。
第一次写网络流,以后还要多加努力。

代码

#include <bits/stdc++.h>
#define MP make_pair
#define PB push_back
#define fi first
#define se second
#define ZERO(x) memset((x), 0, sizeof(x))
#define ALL(x) (x).begin(),(x).end()
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define per(i, a, b) for (int i = (a); i >= (b); --i)
#define QUICKIO \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0);
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pi = pair<int,int>;
// 做题解 const int MAXN=1005;
//const int MAXM=3005;
const int INF=0x3f3f3f3f;
struct Edge
{
int from,to,cap,flow;
Edge(int f,int t,int c,int fl):from(f),to(t),cap(c),flow(fl) {}
}; struct Dinic
{
int n,m,s,t;
vector<Edge> edges;
vector<int> G[MAXN];
void AddEdge(int _f,int _t,int _c)
{
edges.PB(Edge(_f,_t,_c,0));
edges.PB(Edge(_t,_f,0,0));
m=edges.size();
G[_f].PB(m-2);
G[_t].PB(m-1);
}
bool vis[MAXN];
int d[MAXN],cur[MAXN]; bool BFS()
{
ZERO(vis);
queue<int> q;
q.push(s);
d[s]=0;
vis[s]=true;
while(!q.empty())
{
int x=q.front(); q.pop();
rep(i,0,G[x].size()-1)
{
Edge& e=edges[G[x][i]];
if(!vis[e.to] && e.cap>e.flow)
{
vis[e.to]=true;
d[e.to]=d[x]+1;
q.push(e.to);
}
}
}
return vis[t];
} int DFS(int x,int a)
{
if(x==t||a==0) return a;
int flow=0,f;
for(int& i=cur[x]; i<G[x].size();++i)
{
Edge& e=edges[G[x][i]];
if(d[x]+1==d[e.to] && (f=DFS(e.to,min(a,e.cap-e.flow)))>0)
{
e.flow+=f;
edges[G[x][i]^1].flow-=f;
flow+=f;
a-=f;
if(a==0) break;
}
}
return flow;
} int MaxFlow(int s,int t)
{
this->s=s; this->t=t;
int flow=0;
while(BFS())
{
ZERO(cur);
flow+=DFS(s,INF);
}
return flow;
}
}; int main()
{
Dinic dinic;
int n,m;
cin>>n>>m;
dinic.n=2*n+2;
//dinic.s=0; dinic.t=n+1;
ll ta=0,tb=0;
rep(i,1,n)
{
int tmp; cin>>tmp;
dinic.AddEdge(0,i,tmp);
ta+=tmp;
}
rep(i,1,n)
{
int tmp; cin>>tmp;
dinic.AddEdge(i+n,2*n+1,tmp);
tb+=tmp;
}
rep(i,1,n)
dinic.AddEdge(i,i+n,INF);
rep(i,1,m)
{
int a,b; cin>>a>>b;
dinic.AddEdge(a,b+n,INF);
dinic.AddEdge(b,a+n,INF);
}
int mf=dinic.MaxFlow(0,2*n+1);
if(mf==ta && mf==tb)
{
cout<<"YES"<<endl;
int f[105][105];
ZERO(f);
for(int i=0;i<dinic.m;i+=2)
{
int v=dinic.edges[i].to,u=dinic.edges[i^1].to;
//cout<<u<<" "<<v-n<<" "<<dinic.edges[i].flow<<endl;
if(u>=1 && u<=n)
{
f[u][v-n]=dinic.edges[i].flow;
} }
rep(i,1,n)
{
rep(j,1,n)
{
cout<<string(j==1 ? "" : " ")<<f[i][j];
}
cout<<endl;
}
}
else cout<<"NO"<<endl;
return 0;
}

「日常训练」 Soldier and Traveling (CFR304D2E)的更多相关文章

  1. 「日常训练」 Soldier and Number Game (CFR304D2D)

    题意 (Codeforces 546D) 给定一个数x=a!b!" role="presentation">x=a!b!x=a!b!的形式,问其中有几个质因数. 分 ...

  2. 「日常训练」 Soldier and Cards (CFR304D2C)

    题意 (Codeforces 546C) 按照指定的规则打牌,问谁胜或无穷尽. 分析 又是一条模拟,用set+queue(这里手写了)处理即可.注意到两种局势"1 234"和&qu ...

  3. 「日常训练」Soldier and Badges (CFR304D2B)

    题意 (Codeforces 546B) 问对一个序列最少需要增减几个1能使其彼此不同. 分析 模拟处理.需要注意的是,尽管题目中说了an<=3000,问题是,如果一群a全是3000呢(滑稽), ...

  4. 「日常训练」ZgukistringZ(Codeforces Round #307 Div. 2 B)

    题意与分析(CodeForces 551B) 这他妈哪里是日常训练,这是日常弟中弟. 题意是这样的,给出一个字符串A,再给出两个字符串B,C,求A中任意量字符交换后(不限制次数)能够得到的使B,C作为 ...

  5. 「日常训练」 Fire!(UVA-11624)

    与其说是训练不如说是重温.重新写了Java版本的代码. import java.util.*; import java.math.*; import java.io.BufferedInputStre ...

  6. 「日常训练」COMMON 约数研究(HYSBZ-1968)

    题意与分析 感谢https://www.cnblogs.com/Leohh/p/7512960.html的题解.这题话说原来不在我的训练范围,正好有个同学问我,我就拿来做做.数学果然不是我擅长的啊,这 ...

  7. 「日常训练」 Mike and Fun (CFR305D2B)

    题意(CodeForces 548B) 每次对01矩阵中的一位取反,问每次操作后,单列中最长连续1的长度. 分析 非常非常简单,但是我当时训练的时候WA了四次...无力吐槽了,人间 不值得.jpg 代 ...

  8. 「日常训练」Common Subexpression Elimination(UVa-12219)

    今天做的题目就是抱佛脚2333 懂的都懂. 这条题目干了好几天,最后还是参考别人的代码敲出来了,但是自己独立思考了两天多,还是有收获的. 思路分析 做这条题我是先按照之前的那条题目(The SetSt ...

  9. 「日常训练」Magic Stones(CodeForces-1110E)

    题意 给定两个数组c和t,可以对c数组中的任何元素变换\(c_i\)​成\(c_{i+1}+c_{i-1}-c_i\)​,问c数组在若干次变换后能否变换成t数组. 分析 这种魔法题目我是同样的没做过. ...

随机推荐

  1. Linux使用sz、rz命令下载、上传文件

    1.安装服务 yum -y install lrzsz 2.上传命令:rz 使用rz命令,会调用系统的资源管理器,选择文件进行上传即可.上传的文件默认保存linux当前所在目录 3.下载命令:sz 根 ...

  2. Spring Boot 配置文件详解:Properties和YAML

    一.配置文件的生效顺序,会对值进行覆盖: 1. @TestPropertySource 注解 2. 命令行参数 3. Java系统属性(System.getProperties()) 4. 操作系统环 ...

  3. JavaScript创建对象的三种方法

    在 JavaScript 中我们知道无法通过类来创建对象,那么如何创建对象呢? (1)通过“字面量”方式创建对象 将你的信息写到{ }中,并赋值给一个变量,此时这个变量就是一个对象,例: var ga ...

  4. 话说"登录页面"怎么测试

    今天无聊突然想起web登录页面怎么测试,看似简单的问题杀机重重,怎么说呢,一般没有测试思维的人说简单啦,主要有以下几点 .1.账号密码框输入正确的a-z,A-Z,0-9字符,特殊的字符组合测试.2.账 ...

  5. Oracle中的一些查询语句及其执行顺序

    查询条件: 1)LIKE:模糊查询,需要借助两个通配符,%:表示0到多个字符:_:标识单个字符. 2)IN(list):用来取出符合列表范围中的数据. 3)NOT IN(list): 取出不符合此列表 ...

  6. c#总结最近的几项重要代码

    java的代码就不说了,毕竟不是我的主业. 1.c#数据库连接池Hikari. (1)动态加载各类数据库驱动 (2)支持简单配置文件 (3)支持按照名称多数据库调用 (4)使用简洁 单数据库使用: H ...

  7. BZOJ2580: [Usaco2012 Jan]Video Game(AC自动机)

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 159  Solved: 110[Submit][Status][Discuss] Descriptio ...

  8. maven 打包失败 提示找不到jar的问题

    服务打包的时候发现打包失败,查看原因大概是找不到jar包,但是本地仓库有.最终的解决的办法是使用maven 命令重新把jar包安装到本地仓库. 命令如下:mvn install:install-fil ...

  9. 虚拟内存设置(解决linux内存不够情况)

    一.      虚拟内存介绍 背景介绍 Memory指机器物理内存,读写速度低于CPU一个量级,但是高于磁盘不止一个量级.所以,程序和数据如果在内存的话,会有非常快的读写速度.但是,内存的造价是要高于 ...

  10. 【linux基于Postfix和Dovecot邮件系统的搭建】

    一:PostFixe和Dovecot的简单介绍 Postfix postfix是Wietse Venema在IBM的GPL协议之下开发的MTA(邮件传输代理)软件.postfix是Wietse Ven ...