【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

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 }

 

posted @ 2017-03-26 13:23  cot  阅读(194)  评论(0编辑  收藏  举报