• 【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
    ", ans );
    163     return 0;
    164 }
  • 相关阅读:
    Python Data Analysis Library¶
    matadon/mizuno
    MySQL 5.1参考手册
    Apache Derby: Quick Start
    JRuby大捷:ThoughtWorks宣布Mingle发布在即
    RailsWithH2InJNDIOnJetty
    Embedded Jetty and Spring: The Lightweight Antidote for Java EE Complexity
    window下安装解压缩版mysql/zip压缩文件包非install安装程序
    Chapter 9. Extending Workbench
    Mysql手动增加一列_Blog of Grow_百度空间
  • 原文地址:https://www.cnblogs.com/cocottt/p/6622530.html
Copyright © 2020-2023  润新知