1. 程式人生 > >[BZOJ 3931][CQOI2015]網絡吞吐量(SPFA+網絡流)

[BZOJ 3931][CQOI2015]網絡吞吐量(SPFA+網絡流)

說了 路由轉發 數據 實現 typedef 哪些 pac mem 計算機

Description

路由是指通過計算機網絡把信息從源地址傳輸到目的地址的活動,也是計算機網絡設計中的重點和難點。網絡中實現路由轉發的硬件設備稱為路由器。為了使數據包最快的到達目的地,路由器需要選擇最優的路徑轉發數據包。例如在常用的路由算法OSPF(開放式最短路徑優先)中,路由器會使用經典的Dijkstra算法計算最短路徑,然後盡量沿最短路徑轉發數據包。現在,若已知一個計算機網絡中各路由器間的連接情況,以及各個路由器的最大吞吐量(即每秒能轉發的數據包數量),假設所有數據包一定沿最短路徑轉發,試計算從路由器1到路由器n的網絡的最大吞吐量。計算中忽略轉發及傳輸的時間開銷,不考慮鏈路的帶寬限制,即認為數據包可以瞬間通過網絡。路由器1到路由器n作為起點和終點,自身的吞吐量不用考慮,網絡上也不存在將1和n直接相連的鏈路。

Solution

裸題?

先求最短路看哪些邊會被用到,拆點跑一下網絡流

(雖然說了“會使用經典的Dijkstra算法計算最短路徑”,我還是萬年SPFA)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<vector>
#define INF 1LL<<60
using namespace std;
typedef 
long long LL; vector<int>G[505]; int n,m,s,t,head1[505],head2[1005],level[1005],cnt1=0,cnt2=0; LL dis[505]; bool inq[505]; struct Node { int next,to; LL w; }Edges1[200005],Edges2[500005]; LL read() { LL x=0,f=1;char c=getchar(); while(c<0||c>9){ if(c==-)f=-1;c=getchar(); }
while(c>=0&&c<=9){ x=x*10+c-0;c=getchar(); } return x*f; } void addedge1(int u,int v,LL w) { Edges1[cnt1].next=head1[u]; head1[u]=cnt1; Edges1[cnt1].to=v; Edges1[cnt1++].w=w; } void addedge2(int u,int v,LL w) { Edges2[cnt2].next=head2[u]; head2[u]=cnt2; Edges2[cnt2].to=v; Edges2[cnt2++].w=w; } void insert(int u,int v,LL w) { addedge2(u,v,w); addedge2(v,u,0); } queue<int>q; void SPFA() { for(int i=1;i<=n;i++)dis[i]=INF; q.push(1);inq[1]=1,dis[1]=0; while(!q.empty()) { int u=q.front(); q.pop(),inq[u]=0; for(int i=head1[u];~i;i=Edges1[i].next) { int v=Edges1[i].to; if(dis[v]>=dis[u]+Edges1[i].w) { dis[v]=dis[u]+Edges1[i].w; G[u].push_back(i),G[v].push_back(i); if(!inq[v]) inq[v]=1,q.push(v); } } } } bool bfs() { memset(level,-1,sizeof(level)); level[s]=0;q.push(s); while(!q.empty()) { int u=q.front();q.pop(); for(int i=head2[u];~i;i=Edges2[i].next) { int v=Edges2[i].to; if(Edges2[i].w&&level[v]==-1) level[v]=level[u]+1,q.push(v); } } if(level[t]==-1)return false; return true; } LL dfs(int u,LL f) { if(u==t)return f; LL flow=0,d; for(int i=head2[u];~i&&flow<f;i=Edges2[i].next) { int v=Edges2[i].to; if(level[v]==level[u]+1&&Edges2[i].w) { d=dfs(v,min(Edges2[i].w,f-flow)); flow+=d; Edges2[i].w-=d; Edges2[i^1].w+=d; } } if(!flow)level[u]=-1; return flow; } void Dinic() { LL res=0,d; while(bfs()) { while(d=dfs(s,INF)) res+=d; } printf("%lld\n",res); } int main() { memset(head1,-1,sizeof(head1)); memset(head2,-1,sizeof(head2)); n=read(),m=read(); for(int i=1;i<=m;i++) { int u=read(),v=read(); LL w=read(); addedge1(u,v,w); addedge1(v,u,w); } s=1,t=2*n; for(int i=1;i<=n;i++) { int x=read(); if(i==1||i==n) { insert(i,i+n,INF); continue; } insert(i,i+n,x); } SPFA(); for(int u=1;u<=n;u++) { for(int i=0;i<G[u].size();i++) { int j=G[u][i]; int v=Edges1[j].to; if(dis[v]==dis[u]+Edges1[j].w) insert(u+n,v,INF); } } Dinic(); return 0; }

[BZOJ 3931][CQOI2015]網絡吞吐量(SPFA+網絡流)