题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1442
在某个国家有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。Input示例
4 4 1 2 6 3 3 5 3 1 1 2 2 3 3 4 4 2Output示例
YES最大流求解,源点连城市流量ai,城市连汇点流量bi,下面的边是无向图,拆点后建有向的就可以了,最后判断满流
#include <queue> #include <vector> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int maxn = 1010; struct edge { int to, cap, rev; edge(int a, int b, int c) { to = a; cap = b; rev = c; } }; vector<edge>g[maxn]; int level[maxn], iter[maxn]; void addedge(int from,int to,int cap) { g[from].push_back(edge( to,cap,g[to].size() )); g[to].push_back(edge( from,0,g[from].size() - 1 )); } void bfs(int s) { memset(level, -1, sizeof(level)); queue<int>que; level[s] = 0; que.push(s); while (!que.empty()) { int u = que.front(); que.pop(); for (int i = 0; i < g[u].size(); i++) { edge &e = g[u][i]; if (e.cap > 0 && level[e.to] < 0) { level[e.to] = level[u] + 1; que.push(e.to); } } } } int dfs(int v, int t, int f) { if (v == t) { return f; } for (int &i = iter[v]; i < g[v].size(); i++) { edge &e = g[v][i]; if (e.cap > 0 && level[v] < level[e.to]) { int d = dfs(e.to, t, min(f, e.cap)); if (d > 0) { e.cap -= d; g[e.to][e.rev].cap += d; return d; } } } return 0; } int maxflow(int s, int t) { int flow = 0; while (1) { bfs(s); if (level[t] < 0) { return flow; } memset(iter, 0, sizeof(iter)); int f; while ((f = dfs(s, t, inf) )> 0) { flow += f; } } } int main() { //freopen("C://input.txt", "r", stdin); int n, m; scanf("%d%d", &n, &m); int sum1, sum2; sum1 = sum2 = 0; int a, b; for (int i = 1; i <= n; i++) { scanf("%d", &a); addedge(i, i + n, inf); addedge(0, i, a); sum1 += a; } for (int i = 1; i <= n; i++) { scanf("%d", &b); addedge(i + n, 2 * n + 1, b); sum2 += b; } for (int i = 0; i < m; i++) { scanf("%d%d", &a, &b); addedge(a, b + n, inf); addedge(b, a + n, inf); } int ans = maxflow(0, 2 * n + 1); if (ans == sum2 && sum2 == sum1) { printf("YES\n"); } else { printf("NO\n"); } return 0; }
51nod 1442 士兵的旅行(最大流)
猜你喜欢
转载自blog.csdn.net/Evildoer_llc/article/details/83247052
今日推荐
周排行