网络吞吐量 [CQOI2015] [网络流]

Posted iBilllee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络吞吐量 [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

首先要把最短路的网络建出来,如何建网?

跑一边SPFA,对于一条边u->v,如果dis[u]+e[i].dis==dis[v],那么这条路就在最短路网中。

建完网后,因为限制流量于点上而不是边上,所以要拆点为边

(如 ——@——   ->  ——O——a——O——)

连向点a的就连在a左边的点,从a出发的就从a右边的点连出 (可以分别命名为 a,a+n)

从而连接a,a+n的边流量限制为 给定条件,其他边都为INF。

此题请注意值的大小!,务必开long long,inf要开大 (第一遍WA成0分)

 

Code

技术分享图片
  1 #include<queue>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 #define ll long long
  7 #define RG register ll
  8 #define rep(i,a,b)    for(RG i=a;i<=b;i++)
  9 #define per(i,a,b)    for(RG i=a;i>=b;i--)
 10 #define inf (1ll<<60)
 11 #define maxn 2005
 12 #define maxm 100005
 13 using namespace std;
 14 ll n,m,ct,cnt=1,S,T;
 15 ll hd[maxn],head[maxn],step[maxn],dis[maxn],vis[maxn];
 16 struct Edge{
 17     ll u,v,val,next;
 18 }edge[maxm<<1];
 19 struct E{
 20     ll v,next,fl;
 21 }e[maxm<<2];
 22 inline ll read()
 23 {
 24     ll x=0,f=1;char c=getchar();
 25     while(c<0||c>9){if(c==-)f=-1;c=getchar();}
 26     while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
 27     return x*f;
 28 }
 29 
 30 inline void ad(ll u,ll v,ll val)
 31 {
 32     edge[++ct].u=u,edge[ct].v=v,edge[ct].val=val,edge[ct].next=hd[u],hd[u]=ct,swap(u,v);
 33     edge[++ct].u=u,edge[ct].v=v,edge[ct].val=val,edge[ct].next=hd[u],hd[u]=ct;
 34 }
 35 
 36 inline void add(ll u,ll v,ll fl)
 37 {
 38     e[++cnt].v=v,e[cnt].fl=fl,e[cnt].next=head[u],head[u]=cnt,swap(u,v);
 39     e[++cnt].v=v,e[cnt].fl=0 ,e[cnt].next=head[u],head[u]=cnt;
 40 }
 41 
 42 void SPFA()
 43 {
 44     queue<ll> que;
 45     memset(dis,63,sizeof(dis));
 46     dis[1]=0,que.push(1);
 47     RG u,v;
 48     while(!que.empty())
 49     {
 50         u=que.front(),que.pop();vis[u]=0;
 51         for(RG i=hd[u];i;i=edge[i].next)
 52         {
 53             v=edge[i].v;
 54             if(dis[v]>dis[u]+edge[i].val)
 55             {
 56                 dis[v]=dis[u]+edge[i].val;
 57                 if(!vis[v])    vis[v]=1,que.push(v);
 58             }
 59         }
 60     }
 61 }
 62 
 63 ll bfs()
 64 {
 65     queue<ll> que;
 66     memset(step,-1,sizeof(step));step[S]=0,que.push(S);
 67     RG u,v;
 68     while(!que.empty())
 69     {
 70         u=que.front(),que.pop();
 71         for(RG i=head[u];i;i=e[i].next)
 72         {
 73             v=e[i].v;
 74             if(e[i].fl>0&&step[v]==-1)
 75                 step[v]=step[u]+1,que.push(v);
 76         }
 77     }
 78     return (step[T]!=-1);
 79 }
 80 
 81 ll dfs(ll u,ll res)
 82 {
 83     if(u==T||!res)    return res;
 84     ll rem=res;
 85     for(ll i=head[u];i;i=e[i].next)
 86     {
 87         ll v=e[i].v;
 88         if(step[v]==step[u]+1&&e[i].fl>0)
 89         {
 90             ll fl=dfs(v,min(rem,e[i].fl));
 91             e[i].fl-=fl,e[i^1].fl+=fl;
 92             rem-=fl;
 93             if(!rem)    break;
 94         }
 95     }
 96     if(rem)    step[u]=-1;
 97     return res-rem;
 98 }
 99 
100 void Dinic()
101 {
102     ll ans=0;
103     while(bfs())
104         ans+=dfs(S,inf);
105     printf("%lld",ans);
106 }
107 
108 int main()
109 {
110     n=read(),m=read(),S=1,T=(n<<1);
111     RG u,v,val;
112     rep(i,1,m) u=read(),v=read(),val=read(),ad(u,v,val);
113     SPFA();
114     rep(i,1,ct)
115     {
116         u=edge[i].u,v=edge[i].v;
117         if(dis[u]+edge[i].val==dis[v])
118             add(u+n,v,inf);
119     }
120     read();add(1,1+n,inf),add(n,n<<1,inf);
121     rep(i,2,n-1)
122         val=read(),add(i,i+n,val);
123     read();
124     Dinic();
125     return 0;
126 }
>>点击查看代码<<

 

以上是关于网络吞吐量 [CQOI2015] [网络流]的主要内容,如果未能解决你的问题,请参考以下文章

网络吞吐量 [CQOI2015] [网络流]

BZOJ3931 [CQOI2015]网络吞吐量(最大流)

bzoj 3931 [CQOI2015]网络吞吐量(最短路,最大流)

[CQOI2015] 网络吞吐量 - 最大流,最短路

[BZOJ 3931][CQOI2015]网络吞吐量(SPFA+网络流)

[CQOI2015]网络吞吐量(最短路+最大流)