• 3931: [CQOI2015]网络吞吐量【网络流】


    网络吞吐量
    (network)
    题目描述
    路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点。网络中实现
    路由转发的硬件设备称为路由器。为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包。例如,
    在常用的路由算法OSPF(开放式最短路径优先)中,路由器会使用经典的Dijkstra算法计算最短路径,然后尽量沿最短
    路径转发数据包。
    现在,若已知一个计算机网络中各路由器间的连接情况,以及各个路由器的最大吞吐量(即每秒能转发的数据包数
    量),假设所有数据包一定沿最短路径转发,试计算从路由器1到路由器n的网络的最大吞吐量。计算中忽略转发及传
    输的时间开销,不考虑链路的带宽限制,即认为数据包可以瞬间通过网络。路由器1到路由器n作为起点和终点,自身
    的吞吐量不用考虑,网络上也不存在将1和n直接相连的链路。
    输入格式
    输入文件第一行包含两个空格分开的正整数n和m,分别表示路由器数量和链路的数量。网络中的路由器使用1到n编
    号。
    接下来m行,每行包含三个空格分开的正整数a、b和d,表示从路由器a到路由器b存在一条距离为d的双向链路。
    接下来n行,每行包含一个正整数c,分别给出每一个路由器的吞吐量。
    输出格式
    输出一个整数,为题目所求吞吐量。
    输入样例
    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
    输出样例
    70

    思路:首先跑最一遍短路,然后显然网络流上的边得是必须边嘛,然后限制是在点上的,因此需要拆点,跑一边maxflow即可

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<queue>
      5 #define maxn 400009
      6 #define inf ((1LL<<63)-1)
      7 #define ll long long
      8 using namespace std;
      9 ll head[maxn],next[maxn],point[maxn],now,p[maxn],flow[maxn];
     10 ll n,m,value[maxn],dist[maxn],dis[maxn],x[maxn],y[maxn],v[maxn];
     11 void add(ll x,ll y,ll v)
     12 {
     13     next[++now]=head[x];
     14     head[x]=now;
     15     point[now]=y;
     16     value[now]=v;
     17 }
     18 void add2(ll x,ll y,ll v)
     19 {
     20     next[++now]=head[x];
     21     head[x]=now;
     22     point[now]=y;
     23     flow[now]=v;
     24     next[++now]=head[y];
     25     head[y]=now;
     26     point[now]=x;
     27     flow[now]=0;
     28 }
     29 void spfa(ll s)
     30 {
     31     memset(dist,-1,sizeof(dist));
     32     int visit[maxn]={0};
     33     visit[s]=1;
     34     queue<ll>q;
     35     q.push(s);
     36     dist[s]=0;
     37     while(!q.empty())
     38     {
     39         int u=q.front();
     40         q.pop();
     41         visit[u]=0;
     42         for(int i=head[u];i;i=next[i])
     43         {
     44             ll k=point[i];
     45             if(dist[k]==-1 || dist[u]+value[i]<dist[k])
     46             {
     47                 dist[k]=dist[u]+value[i];
     48                 p[k]=u;
     49                 if(!visit[k])
     50                 {
     51                     visit[k]=1;
     52                     q.push(k);
     53                 }
     54             }
     55         }
     56     }
     57 }
     58 int bfs(ll s,ll t)
     59 {
     60     queue<ll>q;
     61     memset(dis,-1,sizeof(dis));
     62     q.push(s);
     63     dis[s]=0;
     64     while(!q.empty())
     65     {
     66         ll u=q.front();
     67         q.pop();
     68         for(int i=head[u];i;i=next[i])
     69         {
     70             ll k=point[i];
     71             if(dis[k]==-1 && flow[i])
     72             {
     73                 dis[k]=dis[u]+1;
     74                 q.push(k);
     75             }
     76         }
     77     }
     78     return dis[t]!=-1;
     79 }
     80 ll dfs(ll s,ll d,ll t)
     81 {
     82     if(s==t)return d;
     83     ll res=0;
     84     for(int i=head[s];i&&res<d;i=next[i])
     85     {
     86         ll u=point[i];
     87         if(flow[i] && dis[u]==dis[s]+1)
     88         {
     89             ll dd=dfs(u,min(flow[i],d-res),t);
     90             if(dd)
     91             {
     92                 flow[i]-=dd;
     93                 flow[((i-1)^1)+1]+=dd;
     94                 res+=dd;
     95             }
     96         }
     97     }
     98     if(res==0)dis[s]=-1;
     99     return res;
    100 }
    101 int main()
    102 {
    103         scanf("%lld%lld",&n,&m);
    104         for(int i=1;i<=m;i++)
    105         {
    106                 scanf("%lld%lld%lld",&x[i],&y[i],&v[i]);
    107                 add(x[i],y[i],v[i]);
    108                 add(y[i],x[i],v[i]);
    109         }
    110         spfa(1);
    111         memset(head,0,sizeof(head));now=0;
    112     for(int i=1;i<=m;i++)
    113     {
    114         if(dist[x[i]] + v[i] == dist[y[i]])
    115         {
    116             add2(x[i]+n,y[i],inf);
    117         }
    118         if(dist[y[i]] + v[i] == dist[x[i]])
    119         {
    120             add2(y[i]+n,x[i],inf);
    121         }
    122     }
    123     ll b;
    124         for(int i=1;i<=n;i++)
    125     {
    126         scanf("%lld",&b);
    127         add2(i,i + n,(i==1||i==n)?inf:b);
    128     }
    129     ll ans=0;
    130     while(bfs(1 ,n + n))
    131     {
    132         ans += dfs(1 ,inf ,n + n);
    133     }
    134     printf("%lld
    ",ans);
    135         return 0;
    136 }
  • 相关阅读:
    网络安全之常见攻击
    引入element-ui
    引入sass
    浏览器解析流程
    JDK8 HashMap--removeNode()移除节点方法
    JDK8 HashMap--treeify()树形化方法
    JDK1.8 HashMap--treeifyBin()方法
    二叉查找树ADT
    队列ADT

  • 原文地址:https://www.cnblogs.com/philippica/p/4415638.html
Copyright © 2020-2023  润新知