Barricade
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1418 Accepted Submission(s): 417
Problem Description
The empire is under attack again. The general of empire is planning to defend his castle. The land can be seen as N towns and M roads, and each road has the same length and connects two towns. The town numbered 1 is where general's castle is located, and the town numbered N is where the enemies are staying. The general supposes that the enemies would choose a shortest path. He knows his army is not ready to fight and he needs more time. Consequently he decides to put some barricades on some roads to slow down his enemies. Now, he asks you to find a way to set these barricades to make sure the enemies would meet at least one of them. Moreover, the barricade on the i-th road requires wi units of wood. Because of lacking resources, you need to use as less wood as possible.
Input
The first line of input contains an integer t, then t test cases follow.
For each test case, in the first line there are two integers N(N≤1000) and M(M≤10000).
The i-the line of the next M lines describes the i-th edge with three integers u,v and w where 0≤w≤1000 denoting an edge between u and v of barricade cost w.
For each test case, in the first line there are two integers N(N≤1000) and M(M≤10000).
The i-the line of the next M lines describes the i-th edge with three integers u,v and w where 0≤w≤1000 denoting an edge between u and v of barricade cost w.
Output
For each test cases, output the minimum wood cost.
Sample Input
1
4 4
1 2 1
2 4 2
3 1 3
4 3 4
Sample Output
4
Source
题目链接:HDU 5889
去年的青岛网络赛一道题,当时只会最短路算法就不会做这水题…………,然而其他几道真正的水题当时也不会做……真是太差劲了……
跑一遍最短路后把最短路上的边加入网络流计算最小割即可,题目说边权相同直接BFS出最短距离就好了。
把dx打成d狂TLE(我可能做了假题目),然后这题有个细节要注意一下,虽然给的是无向图,但是最短路网络中要是有向的,如果当成双向边加入网络流就会WA。
看下这个例子就知道了,实际上1-2-3-4这条路径并不是到最短路径,但由于双向边的关系会使得这条路径连通,导致多出来的1流量流到4
对应数据:
100
4 4
1 4 1
1 2 1
2 3 1
3 4 1
若添加双向边到网络流中则答案变成2,正确的为1
代码:
#include <stdio.h> #include <bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f #define LC(x) (x<<1) #define RC(x) ((x<<1)+1) #define MID(x,y) ((x+y)>>1) #define CLR(arr,val) memset(arr,val,sizeof(arr)) #define FAST_IO ios::sync_with_stdio(false);cin.tie(0); typedef pair<int, int> pii; typedef long long LL; const double PI = acos(-1.0); const int N = 1010; const int M = 10010; struct Edge { int to, nxt, dx, data; Edge() {} Edge(int _to, int _nxt, int _dx, int _data): to(_to), nxt(_nxt), dx(_dx), data(_data) {} }; struct edge { int to, nxt, cap; edge() {} edge(int _to, int _nxt, int _cap): to(_to), nxt(_nxt), cap(_cap) {} }; Edge E[M << 1]; edge e[M << 1]; int H[N], h[N], tot, Tot; int dx[N], d[N]; void init() { CLR(H, -1); CLR(h, -1); tot = 0; Tot = 0; CLR(dx, INF); } inline void addE(int s, int t, int D, int c) { E[Tot] = Edge(t, H[s], D, c); H[s] = Tot++; } inline void adde(int s, int t, int c) { e[tot] = edge(t, h[s], c); h[s] = tot++; e[tot] = edge(s, h[t], 0); h[t] = tot++; } void BFS(int s) { queue<int>Q; Q.push(s); dx[s] = 0; while (!Q.empty()) { int u = Q.front(); Q.pop(); for (int i = H[u]; ~i; i = E[i].nxt) { int v = E[i].to; if (dx[v] == INF) { dx[v] = dx[u] + 1; Q.push(v); } } } } int bfs(int s, int t) { CLR(d, -1); d[s] = 0; queue<int>Q; Q.push(s); while (!Q.empty()) { int u = Q.front(); Q.pop(); for (int i = h[u]; ~i; i = e[i].nxt) { int v = e[i].to; if (d[v] == -1 && e[i].cap > 0) { d[v] = d[u] + 1; if (v == t) return 1; Q.push(v); } } } return ~d[t]; } int dfs(int s, int t, int f) { if (s == t || !f) return f; int ret = 0; for (int i = h[s]; ~i; i = e[i].nxt) { int v = e[i].to; if (d[v] == d[s] + 1 && e[i].cap > 0) { int df = dfs(v, t, min(f, e[i].cap)); if (df > 0) { e[i].cap -= df; e[i ^ 1].cap += df; ret += df; f -= df; if (!f) break; } } } if (!ret) d[s] = -1; return ret; } int dinic(int s, int t) { int ret = 0; while (bfs(s, t)) ret += dfs(s, t, INF); return ret; } int main(void) { int tcase, n, m, a, b, c, i; scanf("%d", &tcase); while (tcase--) { init(); scanf("%d%d", &n, &m); for (i = 0; i < m; ++i) { scanf("%d%d%d", &a, &b, &c); addE(a, b, 1, c); addE(b, a, 1, c); } BFS(1); for (int u = 1; u <= n; ++u) { for (int j = H[u]; ~j; j = E[j].nxt) { int v = E[j].to; if (dx[v] - dx[u] == 1) adde(u, v, E[j].data); } } printf("%d ", dinic(1, n)); } return 0; }