【BZOJ3931】[CQOI2015]网络吞吐量
Description
路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点。网络中实现路由转发的硬件设备称为路由器。为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包。例如在常用的路由算法OSPF(开放式最短路径优先)中,路由器会使用经典的Dijkstra算法计算最短路径,然后尽量沿最短路径转发数据包。现在,若已知一个计算机网络中各路由器间的连接情况,以及各个路由器的最大吞吐量(即每秒能转发的数据包数量),假设所有数据包一定沿最短路径转发,试计算从路由器1到路由器n的网络的最大吞吐量。计算中忽略转发及传输的时间开销,不考虑链路的带宽限制,即认为数据包可以瞬间通过网络。路由器1到路由器n作为起点和终点,自身的吞吐量不用考虑,网络上也不存在将1和n直接相连的链路。
Input
输入文件第一行包含两个空格分开的正整数n和m,分别表示路由器数量和链路的数量。网络中的路由器使用1到n编号。接下来m行,每行包含三个空格分开的正整数a、b和d,表示从路由器a到路由器b存在一条距离为d的双向链路。 接下来n行,每行包含一个正整数c,分别给出每一个路由器的吞吐量。
Output
输出一个整数,为题目所求吞吐量。
Sample Input
7 10
1 2 2
1 5 2
2 4 1
2 3 3
3 7 1
4 5 4
4 3 1
4 6 1
5 6 2
6 7 1
1
100
20
50
20
60
1
1 2 2
1 5 2
2 4 1
2 3 3
3 7 1
4 5 4
4 3 1
4 6 1
5 6 2
6 7 1
1
100
20
50
20
60
1
Sample Output
70
HINT
对于100%的数据,n≤500,m≤100000,d,c≤10^9
Solution
其实看懂题目应该就会做了吧?题目的意思应该就是题解了。。。
意思就是说只有在最短路上的边才能流,每个点有流量限制(除了1和N),求1到N的最大流。
所以直接按题意模拟即可。
Code
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 #include <queue> 6 7 #ifdef WIN32 8 #define LL "%I64d" 9 #else 10 #define LL "%lld" 11 #endif 12 13 #ifdef CT 14 #define debug(...) printf(__VA_ARGS__) 15 #define setfile() 16 #else 17 #define debug(...) 18 #define filename "" 19 #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout) 20 #endif 21 22 #define R register 23 #define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++) 24 #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b)) 25 #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b)) 26 #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0) 27 #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0) 28 #define cabs(_x) ((_x) < 0 ? (- (_x)) : (_x)) 29 char B[1 << 15], *S = B, *T = B; 30 inline int F() 31 { 32 R char ch; R int cnt = 0; R bool minus = 0; 33 while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ; 34 ch == '-' ? minus = 1 : cnt = ch - '0'; 35 while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0'; 36 return minus ? -cnt : cnt; 37 } 38 #define maxn 10010 39 #define maxm 1000010 40 struct edge 41 { 42 int a, b, w; 43 }ee[maxm]; 44 struct Edge 45 { 46 Edge *next, *rev; 47 int to, cap; 48 }*last[maxn], e[maxm], *ecnt = e, *cur[maxn]; 49 inline void link(R int a, R int b, R int w) 50 { 51 *++ecnt = (Edge) {last[a], ecnt + 1, b, w}; last[a] = ecnt; 52 *++ecnt = (Edge) {last[b], ecnt - 1, a, 0}; last[b] = ecnt; 53 } 54 inline void link2(R int a, R int b, R int w) 55 { 56 *++ecnt = (Edge) {last[a], ecnt + 1, b, w}; last[a] = ecnt; 57 *++ecnt = (Edge) {last[b], ecnt - 1, a, w}; last[b] = ecnt; 58 } 59 std::queue<int> q; 60 #define inf 0x7fffffff 61 int dep[maxn], s, t; 62 long long dis[maxn], ans; 63 bool inq[maxn]; 64 inline void spfa() 65 { 66 memset(dis, 63, sizeof (dis)); 67 dis[s] = 0; q.push(s); 68 while (!q.empty()) 69 { 70 R int now = q.front(); q.pop(); inq[now] = 0; 71 for (R Edge *iter = last[now]; iter; iter = iter -> next) 72 { 73 R int pre = iter -> to; 74 if (dis[pre] > dis[now] + iter -> cap) 75 { 76 dis[pre] = dis[now] + iter -> cap; 77 if (!inq[pre]) 78 { 79 q.push(pre); 80 inq[pre] = 1; 81 } 82 } 83 } 84 } 85 } 86 int id[maxn][2]; 87 inline bool bfs() 88 { 89 memset(dep, -1, sizeof (dep)); 90 dep[t] = 0; q.push(t); 91 while (!q.empty()) 92 { 93 R int now = q.front(); q.pop(); 94 for (R Edge *iter = last[now]; iter; iter = iter -> next) 95 { 96 R int pre = iter -> to; 97 if (iter -> rev -> cap && dep[pre] == -1) 98 { 99 dep[pre] = dep[now] + 1; 100 q.push(pre); 101 } 102 } 103 } 104 return dep[s] != -1; 105 } 106 int dfs(R int x, R int f) 107 { 108 if (x == t) return f; 109 R int used = 0; 110 for (R Edge* &iter = cur[x]; iter; iter = iter -> next) 111 { 112 R int pre = iter -> to; 113 if (iter -> cap && dep[x] == dep[pre] + 1) 114 { 115 R int v = dfs(pre, dmin(iter -> cap, f - used)); 116 iter -> cap -= v; 117 iter -> rev -> cap += v; 118 used += v; 119 if (f == used) return f; 120 } 121 } 122 if (!used) dep[x] = -1; 123 return used; 124 } 125 inline void dinic() 126 { 127 while (bfs()) 128 { 129 memcpy(cur, last, sizeof last); 130 ans += dfs(s, inf); 131 } 132 } 133 int main() 134 { 135 // setfile(); 136 R int n = F(), m = F(), cnt = 0; 137 for (R int i = 1; i <= m; ++i) 138 { 139 R int a, b, w; 140 ee[i] = (edge) {a = F(), b = F(), w = F()}; 141 link2(a, b, w); 142 } 143 s = 1; 144 spfa(); 145 memset(last, 0, sizeof last); 146 ecnt = e; 147 for (R int i = 1; i <= n; ++i) 148 { 149 id[i][0] = ++cnt; 150 id[i][1] = ++cnt; 151 link(id[i][0], id[i][1], F()); 152 } 153 s = id[1][1]; t = id[n][0]; 154 for (R int i = 1; i <= m; ++i) 155 { 156 if (dis[ee[i].a] == dis[ee[i].b] + ee[i].w) 157 link(id[ee[i].b][1], id[ee[i].a][0], inf); 158 if (dis[ee[i].b] == dis[ee[i].a] + ee[i].w) 159 link(id[ee[i].a][1], id[ee[i].b][0], inf); 160 } 161 dinic(); 162 printf("%lld\n", ans ); 163 return 0; 164 }