bzoj 1266: [AHOI2006]上学路线route
思路:找出最短路图, 然后求最小割。
1 #include<bits/stdc++.h> 2 #define LL long long 3 4 using namespace std; 5 6 const int N = 507; 7 const int M = 124750; 8 const int inf = 0x3f3f3f3f; 9 10 struct Edge { 11 int u, v, t, c, nx; 12 } edge[2][M << 1]; 13 14 int n, m, S, T, tot[2], head[2][N], d[N], in[N], level[N]; 15 16 void add(int x, int u, int v, int t, int c) { 17 edge[x][tot[x]].u = u; 18 edge[x][tot[x]].v = v; 19 edge[x][tot[x]].t = t; 20 edge[x][tot[x]].c = c; 21 edge[x][tot[x]].nx = head[x][u]; 22 head[x][u] = tot[x]++; 23 } 24 25 void spfa() { 26 queue<int> que; 27 d[1] = 0; que.push(1); in[1] = 1; 28 while(!que.empty()) { 29 int u = que.front(); que.pop(); 30 for(int i = head[0][u]; ~i; i = edge[0][i].nx) { 31 int v = edge[0][i].v, t = edge[0][i].t; 32 if(d[u] + t < d[v]) { 33 d[v] = d[u] + t; 34 if(!in[v]) que.push(v); 35 } 36 } 37 in[u] = 0; 38 } 39 } 40 41 bool bfs() { 42 memset(level, 0, sizeof(level)); 43 queue<int> que; 44 que.push(S); level[S] = 1; 45 while(!que.empty()) { 46 int u = que.front(); que.pop(); 47 if(u == T) return true; 48 for(int i = head[1][u]; ~i; i = edge[1][i].nx) { 49 int v = edge[1][i].v; 50 if(!level[v] && edge[1][i].c > 0) { 51 que.push(v); 52 level[v] = level[u] + 1; 53 } 54 } 55 } 56 return false; 57 } 58 59 int dfs(int u, int p) { 60 if(u == T) return p; 61 int ret = 0; 62 for(int i = head[1][u]; ~i; i = edge[1][i].nx) { 63 int v = edge[1][i].v, c = edge[1][i].c; 64 if(c <= 0 || level[v] != level[u] + 1) continue; 65 int f = dfs(v, min(p - ret, c)); 66 ret += f; 67 edge[1][i].c -= f; 68 edge[1][i ^ 1].c += f; 69 if(ret == p) break; 70 } 71 if(!ret) level[u] = 1; 72 return ret; 73 } 74 75 int Dinic() { 76 int ans = 0; 77 while(bfs()) ans += dfs(S, inf); 78 return ans; 79 } 80 int main() { 81 memset(head, -1, sizeof(head)); 82 memset(d, inf, sizeof(d)); 83 scanf("%d%d", &n, &m); 84 S = 1, T = n; 85 for(int i = 1; i <= m; i++) { 86 int u, v, t, c; 87 scanf("%d%d%d%d", &u, &v, &t, &c); 88 add(0, u, v, t, c); 89 add(0, v, u, t, c); 90 } 91 92 spfa(); 93 94 for(int i = 0; i < tot[0]; i++) { 95 int u = edge[0][i].u; 96 int v = edge[0][i].v; 97 int t = edge[0][i].t; 98 int c = edge[0][i].c; 99 100 if(d[u] + t == d[v]) { 101 add(1, u, v, t, c); 102 add(1, v, u, t, 0); 103 } 104 } 105 106 int ans = Dinic(); 107 108 printf("%d\n", d[n]); 109 printf("%d\n", ans); 110 return 0; 111 }