网络吞吐量
(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 }