Codeforces 546E:士兵的旅行 最大网络流
来源:互联网 发布:网络错误怎么办 编辑:程序博客网 时间:2024/06/04 11:46
51nod上也有这道题,题意就是:
在某个国家有n个城市,他们通过m条无向的道路相连。每个城市有一支军队。第i个城市的军队有ai个士兵。现在士兵开始移动。每个士兵可以呆在原地,或者走到和他所在城市直接相邻的城市,即设每一条边长度为1的话,他离开之后不能距离原来城市大于1。
判断移动之后,能不能使得第i个城市恰好有bi个士兵。
(......)
发现题目一旦像这种有一堆点的起始状态,然后是目标状态的,并且可以用路径来更改每个点的状态的。这种题用最大网络流做准没错。1.将源点与各个点相连,容量就是a[i]。
2.将汇点与各个点相连,容量就是b[i]。
3.将a[i]与a[i+N]相连,容量是INF,表示士兵可以留在自己的城市里面。
4.对于两个城市i与j有边的,将i与j+N相连,将j与i+N相连,容量均为INF,表示士兵可以从这两个城市来回窜。
5.求一下最大流,保证最大流填满了源点的每一条管道,填满了汇点的每一条管道。即最大流等于a[i]之和,也等于b[i]之和,就是YES。否则就是NO。
代码:
#include <iostream>#include <algorithm>#include <cmath>#include <vector>#include <string>#include <cstring>#include <queue>#pragma warning(disable:4996)using namespace std;const int sum = 205;const int INF = 99999999;int cap[sum][sum], flow[sum][sum], a[sum], p[sum];int val[1005];int flag[1005];int sum1, sum2;int N, M;void Edmonds_Karp(){int u, t, result = 0;queue <int> s;while (s.size())s.pop();while (1){memset(a, 0, sizeof(a));memset(p, 0, sizeof(p));a[0] = INF;s.push(0);while (s.size()){u = s.front();s.pop();for (t = 0; t <= M + 1; t++){if (!a[t] && flow[u][t]<cap[u][t]){s.push(t);p[t] = u;a[t] = min(a[u], cap[u][t] - flow[u][t]);//要和之前的那个点,逐一比较,到M时就是整个路径的最小残量 }}}if (a[M + 1] == 0)break;result += a[M + 1];for (u = M + 1; u != 0; u = p[u]){flow[p[u]][u] += a[M + 1];flow[u][p[u]] -= a[M + 1];}}if (sum1 == result&&sum2 == result){cout << "YES" << endl;int i, j;for (i = 1; i <= M/2; i++){for (j = 1; j <= M/2; j++){if (j == 1){cout << flow[i][j + M/2];}else{cout <<" "<<flow[i][j + M/2];}}cout << endl;}}else{cout << "NO" << endl;}}int main(){//freopen("i.txt","r",stdin);//freopen("o.txt","w",stdout);int i, temp, temp1, temp2;cin >> N >> M;sum1 = 0; sum2 = 0;memset(cap, 0, sizeof(cap));for (i = 1; i <= N; i++){cin >> temp;cap[0][i] = temp;sum1 += temp;}for (i = 1; i <= N; i++){cin >> temp;cap[i + N][2 * N + 1] = temp;sum2 += temp;cap[i][i + N] = INF;}for (i = 1; i <= M; i++){cin >> temp1 >> temp2;cap[temp1][temp2 + N] = INF;cap[temp2][temp1 + N] = INF;}M = 2 * N ;Edmonds_Karp();//system("pause");return 0;}
0 0
- Codeforces 546E:士兵的旅行 最大网络流
- 士兵的旅行 【最大流 建模】
- [51NOD] 1442 士兵的旅行 [Dinic][最大流]
- 51nod 1442 士兵的旅行(最大流)
- codeforces 546E (最大流)
- Codeforces 546 E Soldier and Traveling【最大流Dinic+判断残余网络】
- 51nod 1442 士兵的旅行 【 网络费用流 (还存在bug) 】
- 【网络流 最大流】【bzoj1458】士兵占领
- BZOJ 1458: 士兵占领 网络最大流
- codeforces #304 E 546E E. Soldier and Traveling(最大流)
- Codeforces 546E - Soldier and Traveling (最大流)
- Codeforces 546E Soldier and Traveling (最大流)
- Codeforces 546E Soldier and Traveling 最大流 C#实现
- Codeforces Round #290 (Div. 2) E. Fox And Dinner 网络流 最大流
- codeforces 277E 最小费用最大流
- codeforces 78E - Evacuation 最大流
- codeforces-546E. Soldier and Traveling(网络流)
- codeforces 546E. Soldier and Traveling 网络流
- 干货:android实现hessian通信
- 整理分类Android文件(一)
- iOS学习笔记之网络篇文件上传(复杂,详解)
- QQ登录界面01
- ios深度解析之Swift(结构体和类,属性)
- Codeforces 546E:士兵的旅行 最大网络流
- Python数据类型之间的转换
- VPN-VPDN
- MySQL数据库索引
- Objective-C-类和对象
- 获取用户输入的信息,并用Post请求提交
- 读书,还是读数量?
- 进程内核栈、用户栈及 Linux 进程栈和线程栈的区别
- 【转载】新入行程序员须知的8件事