BZOJ3931 [CQOI2015] 网络吞吐量
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3931
Description
路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点。网络中实现路由转发的硬件设备称为路由器。为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包。例如在常用的路由算法OSPF(开放式最短路径优先)中,路由器会使用经典的Dijkstra算法计算最短路径,然后尽量沿最短路径转发数据包。现在,若已知一个计算机网络中各路由器间的连接情况,以及各个路由器的最大吞吐量(即每秒能转发的数据包数量),假设所有数据包一定沿最短路径转发,试计算从路由器1到路由器n的网络的最大吞吐量。计算中忽略转发及传输的时间开销,不考虑链路的带宽限制,即认为数据包可以瞬间通过网络。路由器1到路由器n作为起点和终点,自身的吞吐量不用考虑,网络上也不存在将1和n直接相连的链路。
Input
输入文件第一行包含两个空格分开的正整数n和m,分别表示路由器数量和链路的数量。网络中的路由器使用1到n编号。接下来m行,每行包含三个空格分开的正整数a、b和d,表示从路由器a到路由器b存在一条距离为d的双向链路。 接下来n行,每行包含一个正整数c,分别给出每一个路由器的吞吐量。
Output
输出一个整数,为题目所求吞吐量。
题意即题解——hzwer
然而我对着这道水题debug了一节晚自习,直到第二天中午才AC,因为把一个 || 打成了 && …… 吐出一口老血
看来“Runtime Error”这个QQ签名的确不吉利,一换上写一题炸一题
不过这也有好处:根据《RP导论》(链接:http://www.nocow.cn/index.php/RP%E5%AF%BC%E8%AE%BA),这有利于为即将到来的月考积累RP
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <queue> 6 #define rep(i,l,r) for(int i=l; i<=r; i++) 7 #define clr(x,y) memset(x,y,sizeof(x)) 8 #define travel(x) for(Edge *p=last[x]; p; p=p->pre) 9 typedef long long ll; 10 using namespace std; 11 const ll INF = 100000000000000LL; 12 const int maxn = 510; 13 struct Edge{ 14 Edge *pre,*rev; int to; ll cost; 15 }edge[200010]; 16 Edge *last[maxn<<1],*cur[maxn<<1],*pt; 17 int n,m,x,a[100010],b[100010],c[100010]; 18 bool isin[maxn]; 19 ll ans=0,d[maxn<<1]; 20 queue <int> q; 21 inline int read(){ 22 int ans = 0, f = 1; 23 char c = getchar(); 24 while (!isdigit(c)){ 25 if (c == '-') f = -1; 26 c = getchar(); 27 } 28 while (isdigit(c)){ 29 ans = ans * 10 + c - '0'; 30 c = getchar(); 31 } 32 return ans * f; 33 } 34 inline void addedge(int x,int y,ll z){ 35 pt->pre = last[x]; pt->to = y; pt->cost = z; last[x] = pt++; 36 } 37 inline void add(int x,int y,ll z){ 38 addedge(x,y,z); addedge(y,x,0); last[x]->rev = last[y]; last[y]->rev = last[x]; 39 } 40 void spfa(){ 41 rep(i,1,n) d[i] = INF; d[1] = 0; 42 clr(isin,0); isin[1] = 1; q.push(1); 43 while (!q.empty()){ 44 int now = q.front(); q.pop(); isin[now] = 0; 45 travel(now){ 46 if (d[p->to] > d[now] + p->cost){ 47 d[p->to] = d[now] + p->cost; 48 if (!isin[p->to]){ 49 isin[p->to] = 1; 50 q.push(p->to); 51 } 52 } 53 } 54 } 55 } 56 bool bfs(){ 57 while (!q.empty()) q.pop(); 58 clr(d,-1); d[1] = 0; q.push(1); 59 while (!q.empty()){ 60 int now = q.front(); q.pop(); 61 travel(now){ 62 if (d[p->to] == -1 && p->cost > 0){ 63 d[p->to] = d[now] + 1; 64 q.push(p->to); 65 if (p->to == n<<1) return 1; 66 } 67 } 68 } 69 return 0; 70 } 71 ll dfs(int x,ll flow){ 72 if (x == n<<1 || (!flow)) return flow; ll w = 0; 73 for(Edge *p=cur[x]; p && w < flow; p=p->pre){ 74 if (d[p->to] == d[x] + 1 && p->cost > 0){ 75 ll delta = dfs(p->to,min(p->cost,flow-w)); 76 p->cost -= delta; 77 p->rev->cost += delta; 78 w += delta; 79 if (p->cost) cur[x] = p; 80 } 81 } 82 if (w < flow) d[x] = -1; 83 return w; 84 } 85 int main(){ 86 n = read(); m = read(); clr(last,0); pt = edge; 87 rep(i,1,m){ 88 a[i] = read(); b[i] = read(); c[i] = read(); 89 addedge(a[i],b[i],c[i]); addedge(b[i],a[i],c[i]); 90 } 91 spfa(); 92 clr(last,0); pt = edge; 93 rep(i,1,m){ 94 if (d[a[i]] + c[i] == d[b[i]]){ 95 add(a[i]+n,b[i],INF); 96 } 97 if (d[b[i]] + c[i] == d[a[i]]){ 98 add(b[i]+n,a[i],INF); 99 } 100 } 101 rep(i,1,n){ 102 x = read(); 103 if (i != 1 && i != n) add(i,i+n,x); else add(i,i+n,INF); 104 } 105 while (bfs()){ 106 rep(i,1,n<<1) cur[i] = last[i]; 107 ans += dfs(1,INF); 108 } 109 printf("%lld\n",ans); 110 return 0; 111 }