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 }
View Code

 

posted on 2015-12-18 13:58  ACMICPC  阅读(636)  评论(2编辑  收藏  举报

导航