士兵的旅行 【最大流 建模】
来源:互联网 发布:mac怎么同时开两个窗口 编辑:程序博客网 时间:2024/06/07 21:34
在某个国家有n个城市,他们通过m条无向的道路相连。每个城市有一支军队。第i个城市的军队有ai个士兵。现在士兵开始移动。每个士兵可以呆在原地,或者走到和他所在城市直接相邻的城市,即设每一条边长度为1的话,他离开之后不能距离原来城市大于1。
判断移动之后,能不能使得第i个城市恰好有bi个士兵。
Input
单组测试数据。
第一行有两个整数n和m(1 ≤ n ≤ 100, 0 ≤ m ≤ 200)。
第二行包含n个整数 a1, a2, …, an (0 ≤ ai ≤ 100)。
第三行包含n个整数b1, b2, …, bn (0 ≤ bi ≤ 100)。
接下来m行,每行给出两个整数 p 和q (1 ≤ p, q ≤ n, p ≠ q),表示p和q之间有一条无向的道路。
每两个城市之间最多有一条无向的道路。
Output
如果能够调整成功,输出YES,否则输出NO。
Sample Input
4 4
1 2 6 3
3 5 3 1
1 2
2 3
3 4
4 2
Sample Output
YES
思路 : 像这种的 有多点的开始状态 ,然后又给末时候的状态,最后问能能成功的,就是 常常是最大流问题。。
重点 : 建模
代码
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<cmath>#include<queue>#include<stack>#include<map>#include<vector>#include<set>#define CLR(a,b) memset((a),(b),sizeof(a))#define inf 0x3f3f3f3f#define mod 100009#define LL long long#define M 1000#define ll o<<1#define rr o<<1|1#define lson o<<1,l,mid#define rson o<<1|1,mid+1,rusing namespace std;struct Edge { int from,to,cap,flow,next;}edge[M];int n,m;int head[M],vis[M],dis[M],cur[M],top; queue<int>Q;void init(){ top=0; memset(head,-1,sizeof(head));}void addedge(int a,int b,int c){ Edge e={a,b,c,0,head[a]}; edge[top]=e;head[a]=top++; Edge ee={b,a,0,0,head[b]}; edge[top]=ee;head[b]=top++;}int bfs(int st,int ed){ memset(vis,0,sizeof(vis)); memset(dis,-1,sizeof(dis)); while(!Q.empty()) Q.pop(); vis[st]=1;dis[st]=0; Q.push(st);int now,nexts; while(!Q.empty()) { now=Q.front();Q.pop(); for(int i=head[now];i!=-1;i=edge[i].next) { Edge e=edge[i]; if(!vis[e.to]&&e.cap>e.flow) { vis[e.to]=1; dis[e.to]=dis[now]+1; if(e.to==ed) return 1; Q.push(e.to); } } } return 0;}int dfs(int now,int a,int ed){ if(a==0||now==ed) return a; int flow=0,f; for(int& i=cur[now];i!=-1;i=edge[i].next) { Edge& e=edge[i]; if(dis[e.to]==dis[now]+1&&(f=dfs(e.to,min(a,e.cap-e.flow),ed))>0) { e.flow+=f; edge[i^1].flow-=f; a-=f; flow+=f; if(a==0) break; } } return flow;}int max_flow(int st,int ed){ int flow=0; while(bfs(st,ed)) { memcpy(cur,head,sizeof(head)); flow+=dfs(st,inf,ed); } return flow;}int main(){ int n,m; scanf("%d%d",&n,&m); int st=0;int ed=n<<1|1; //以点0 为源点 ,点2*n+1为汇点 init(); int i,j;int flag; int sum1,sum2; sum1=sum2=0; for(i=1;i<=n;i++)//每个城市的容量 可以当作 源点到其点最大的容量 { // 添加边顶点的顺序 eg不能addedge (i,st,aa); int aa;scanf("%d",&aa); addedge(st,i,aa);//源点与起点连接 addedge(i,i+n,aa);//其点和其镜像点 相连接。这里也可以inf 来填充,边权 。 sum1+=aa; } for(i=1+n;i<=n*2;i++) { int bb;scanf("%d",&bb); addedge(i,ed,bb);// 镜像点与汇点相连接 sum2+=bb; } while(m--) { int a,b,c; scanf("%d%d",&a,&b);// inf 表明 两城市之间可以 无限交换 addedge(a,b+n,inf); addedge(b,a+n,inf); } if(sum1==sum2&&max_flow(st,ed)==sum1) flag=1; else flag=0;//如果能够 改变成功说明 到达汇点的 最大流一定为 所有的士兵个数 printf("%s\n",flag?"YES":"NO"); return 0;}
0 0
- 士兵的旅行 【最大流 建模】
- Codeforces 546E:士兵的旅行 最大网络流
- [51NOD] 1442 士兵的旅行 [Dinic][最大流]
- 51nod 1442 士兵的旅行(最大流)
- 51Nod-1442-士兵的旅行
- 51nod 1442 士兵的旅行 【 网络费用流 (还存在bug) 】
- BZOJ1458 士兵占领 最大流
- 【bzoj1458】士兵占领 最大流
- 【BZOJ1458】士兵占领【最大流】
- BZOJ1458: 士兵占领 最大流
- 【bzoj1458】士兵占领 最大流
- BZOJ1458 士兵占领-最大流
- [bzoj1458]士兵占领 最大流
- 【POJ1087】【最大流建模】
- 【BZOJ1570】【JSOI2008】Blue Mary的旅行 最大流check
- 【bzoj1570】[JSOI2008]Blue Mary的旅行 最大流
- 1570: [JSOI2008]Blue Mary的旅行 最大流
- 【BZOJ1570】[JSOI2008]Blue Mary的旅行【最大流】
- delphi经典大写数字转换函数
- SSL certificate problem: unable to get local issuer certificate
- kafka数据可靠性深度解读
- JVM 原理概要
- Win7系统64位环境下使用Apache——安装Apache2.4时报错“Invalid command Order”问题的解决
- 士兵的旅行 【最大流 建模】
- nginx服务器详细安装过程(使用yum 和 源码包两种安装方式,并说明其区别)
- 《反汇编基础》调用函数时栈的操作
- jsp隐式对象,四个作用域的区别
- java-pdf-(itext+adobe acrobat+pdf模板)生成pdf文件
- 前后端渲染和同构渲染
- 获取签名公钥的代码(未测)
- HttpQueryInfo 用来查询一个HTTP请求的信息。
- Discuz二次开发 教你识别程序目录和文件列表