防卫
1048:2012-12-28 防衛
時間限制:?小敏和小燕是一對好朋友。
他們正在玩一種神奇的游戲,叫Minecraft。
Tech國和Mana國即將要開戰了,小敏帶領Tech國修建了許多的據點,據點之間有一些僅允許單向通行的道路。
小敏正在自信滿滿地準備迎接Mana國的挑戰的時候,小燕無意間在遠處發現了一大堆Creeper……
這個消息瞬間擊倒了小敏。無奈之下,小敏只能在據點上修建一些大炮,保護自己開戰的前線不被Creeper給摧毀。也就是說,要保證所有的Creeper在到達前線陣地之前,就已經被大炮給斃了。
不過在不同的據點上修建大炮的費用不一樣,小敏希望費用最小。
沒有出去道路的據點是前線陣地,Creeper只能從遠處進入沒有進來道路的據點,并且通過道路進入其他的據點。
接下來的一行有n個整數,分別代表每個據點修建大炮的費用。
接下來的m行,每行兩個整數x和y,分別代表有一條道路從x連到y。
?「Solution」
最大流+拆點
「代碼」
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #define maxn 20000 #define INF 1 << 30 using namespace std; struct E {int from, to, tab, next; }edge[maxn]; int dist[maxn], head[maxn], d[maxn], in[maxn], out[maxn], ans, s, t, tot, m, n;void add_edge(int u, int v, int f) {tot++;edge[tot].from = u, edge[tot].to = v, edge[tot].tab = f, edge[tot].next = head[u], head[u] = tot;tot++;edge[tot].from = v, edge[tot].to = u, edge[tot].tab = 0, edge[tot].next = head[v], head[v] = tot; }int dfs(int x, int low) {int a;if (x == t) return low;for (int i = head[x]; i != -1; i = edge[i].next)if (dist[edge[i].to] == dist[x] + 1 && edge[i].tab > 0 && (a = dfs(edge[i].to, min(low, edge[i].tab)))){edge[i].tab -= a, edge[i^1].tab += a;return a;}return 0; }int bfs() {int l, r, k;memset(dist, 0xff, sizeof(dist));dist[s] = 0;d[0] = 0, d[1] = s;l = 0, r = 1;while (l < r){k = d[++l];for (int i = head[k]; i != -1; i = edge[i].next)if (edge[i].tab > 0 && dist[edge[i].to] < 0) dist[edge[i].to] = dist[k] + 1, d[++r] = edge[i].to;}if (dist[t] > 0) return 1; else return 0; }void dinic() {ans = 0;while (bfs()) ans += dfs(s, INF); }int main() {int x, y, f;tot = -1;memset(head,0xff,sizeof(head));scanf("%d%d", &n, &m);s = 2 * n + 1, t = 2 * n + 2;for (int i = 1; i <= n; i++){scanf("%d", &f);add_edge(i, i+n, f);}for (int i = 1; i <= m; i++){scanf("%d%d", &x, &y);in[y]++, out[x]++;add_edge(x+n, y, INF);}for (int i = 1; i <= n; i++){if (in[i] == 0) add_edge(s, i, INF);if (out[i] == 0) add_edge(i+n, t, INF);}dinic();printf("%d\n", ans);return 0; }
總結
- 上一篇: WPS和office办公软件的word同
- 下一篇: 世界上最遥远的距离,是我在if里你在el