CF Soldier and Traveling(最大流SAP)拆点法
2015-06-18 12:46
393 查看
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 city consists of aisoldiers.
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 soldiers
in the i-th city.
Input
First line of input consists of two integers n and m (1 ≤ n ≤ 100, 0 ≤ m ≤ 200).
Next line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 100).
Next line contains n integers b1, b2, ..., bn (0 ≤ bi ≤ 100).
Then m lines follow, each of them consists of two integers p and q (1 ≤ p, q ≤ n, p ≠ q)
denoting that there is an undirected road between cities p and q.
It is guaranteed that there is at most one road between each pair of cities.
Output
If the conditions can not be met output single word "NO".
Otherwise output word "YES" and then n lines,
each of them consisting of n integers. Number in the i-th
line in the j-th column should denote how many soldiers should road from city i to
city j (if i ≠ j)
or how many soldiers should stay in city i (if i = j).
If there are several possible answers you may output any of them.
Sample test(s)
input
output
input
output
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 city consists of aisoldiers.
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 soldiers
in the i-th city.
Input
First line of input consists of two integers n and m (1 ≤ n ≤ 100, 0 ≤ m ≤ 200).
Next line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 100).
Next line contains n integers b1, b2, ..., bn (0 ≤ bi ≤ 100).
Then m lines follow, each of them consists of two integers p and q (1 ≤ p, q ≤ n, p ≠ q)
denoting that there is an undirected road between cities p and q.
It is guaranteed that there is at most one road between each pair of cities.
Output
If the conditions can not be met output single word "NO".
Otherwise output word "YES" and then n lines,
each of them consisting of n integers. Number in the i-th
line in the j-th column should denote how many soldiers should road from city i to
city j (if i ≠ j)
or how many soldiers should stay in city i (if i = j).
If there are several possible answers you may output any of them.
Sample test(s)
input
4 4 1 2 6 3 3 5 3 1 1 2 2 3 3 4 4 2
output
YES 1 0 0 0 2 0 0 0 0 5 1 0 0 0 2 1
input
2 0 1 2 2 1
output
NO
#include<stdio.h> #include<string.h> #include<queue> #include<algorithm> using namespace std; #define captype int const int MAXN = 510; //点的总数 const int MAXM = 400010; //边的总数 const int INF = 1<<30; struct EDG{ int to,next; captype cap,flow; } edg[MAXM]; int eid,head[MAXN]; int gap[MAXN]; //每种距离(或可认为是高度)点的个数 int dis[MAXN]; //每个点到终点eNode 的最短距离 int cur[MAXN]; //cur[u] 表示从u点出发可流经 cur[u] 号边 int pre[MAXN]; int mapt[105][105]; void init(){ eid=0; memset(head,-1,sizeof(head)); memset(mapt,0,sizeof(mapt)); } //有向边 三个参数,无向边4个参数 void addEdg(int u,int v,captype c,captype rc=0){ edg[eid].to=v; edg[eid].next=head[u]; edg[eid].cap=c; edg[eid].flow=0; head[u]=eid++; edg[eid].to=u; edg[eid].next=head[v]; edg[eid].cap=rc; edg[eid].flow=0; head[v]=eid++; } captype maxFlow_sap(int sNode,int eNode, int n){//n是包括源点和汇点的总点个数,这个一定要注意 memset(gap,0,sizeof(gap)); memset(dis,0,sizeof(dis)); memcpy(cur,head,sizeof(head)); pre[sNode] = -1; gap[0]=n; captype ans=0; //最大流 int u=sNode; while(dis[sNode]<n){ //判断从sNode点有没有流向下一个相邻的点 if(u==eNode){ //找到一条可增流的路 captype Min=INF ; int inser; for(int i=pre[u]; i!=-1; i=pre[edg[i^1].to]) //从这条可增流的路找到最多可增的流量Min if(Min>edg[i].cap-edg[i].flow){ Min=edg[i].cap-edg[i].flow; inser=i; } for(int i=pre[u]; i!=-1; i=pre[edg[i^1].to]){ edg[i].flow+=Min; edg[i^1].flow-=Min; //可回流的边的流量 if(edg[i].to==eNode||edg[i].to==sNode||edg[i^1].to==eNode||edg[i^1].to==sNode) continue; if(edg[i].cap>0){ int tu, tv; tu=edg[i^1].to; tv=edg[i].to-(n-1)/2; mapt[tu][tv]+=Min; } else{ int tu, tv; tu=edg[i].to; tv=edg[i^1].to-(n-1)/2; mapt[tu][tv]-=Min; } } ans+=Min; u=edg[inser^1].to; continue; } bool flag = false; //判断能否从u点出发可往相邻点流 int v; for(int i=cur[u]; i!=-1; i=edg[i].next){ v=edg[i].to; if(edg[i].cap-edg[i].flow>0 && dis[u]==dis[v]+1){ flag=true; cur[u]=pre[v]=i; break; } } if(flag){ u=v; continue; } //如果上面没有找到一个可流的相邻点,则改变出发点u的距离(也可认为是高度)为相邻可流点的最小距离+1 int Mind= n; for(int i=head[u]; i!=-1; i=edg[i].next) if(edg[i].cap-edg[i].flow>0 && Mind>dis[edg[i].to]){ Mind=dis[edg[i].to]; cur[u]=i; } gap[dis[u]]--; if(gap[dis[u]]==0) return ans; //当dis[u]这种距离的点没有了,也就不可能从源点出发找到一条增广流路径 //因为汇点到当前点的距离只有一种,那么从源点到汇点必然经过当前点,然而当前点又没能找到可流向的点,那么必然断流 dis[u]=Mind+1;//如果找到一个可流的相邻点,则距离为相邻点距离+1,如果找不到,则为n+1 gap[dis[u]]++; if(u!=sNode) u=edg[pre[u]^1].to; //退一条边 } return ans; } int main(){ int n,m ,s , t , u,v,c[105],tc; while(scanf("%d%d",&n,&m)>0){ init(); s=0; t=2*n+1; int ans=0; for(int i=1; i<=n; i++){ scanf("%d",&c[i]); ans+=c[i]; addEdg(s,i,c[i]); addEdg(i,i+n,c[i]); } int sum=0; for(int i=1; i<=n; i++) { scanf("%d",&tc); sum+=tc; addEdg(i+n,t,tc); } while(m--){ scanf("%d%d",&u,&v); addEdg(u,v+n,c[u]); addEdg(v,u+n,c[v]); } if(ans!=sum){ printf("NO\n"); continue; } ans -= maxFlow_sap(s,t,t+1); if(ans==0){ printf("YES\n"); for(int i=1; i<=n; i++){ for(int j=1; j<n; j++) printf("%d ",mapt[i][j]); printf("%d\n",mapt[i] ); } } else printf("NO\n"); } }
相关文章推荐
- arduino 红外和超声波库文件下载
- MySQL提示Access denied for user ''@'localhost'”的解决
- iOS 获取手机的型号,系统版本,软件名称,软件版本
- svn=apache搭建常见问题解决
- java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符 分号问题
- 微信商城开发系列第四篇 不写代码玩转微信公众号
- 阅读《构建之法》第13-17章和读《一个程序员的生命周期》有感
- PHP排序算法
- css居中
- 日语学习之沪江N3基础 20150618 -4
- 数据结构 -- 树
- 深入了解mysql它BDB系列(1)---BDB基础知识
- 新款车型防盗器的安装方法
- 归并排序和希尔排序
- <s:if>的用法
- BZOJ 1563 NOI2009 诗人小G 四边形不等式
- 学习过程
- scala调用java api
- Ubuntu 下mysql常用的操作语句
- 排序--折半插入