[BZOJ 3931][CQOI2015]网络吞吐量(SPFA+网络流)
Description
路由是指通過計算機網(wǎng)絡(luò)把信息從源地址傳輸?shù)侥康牡刂返幕顒?#xff0c;也是計算機網(wǎng)絡(luò)設(shè)計中的重點和難點。網(wǎng)絡(luò)中實現(xiàn)路由轉(zhuǎn)發(fā)的硬件設(shè)備稱為路由器。為了使數(shù)據(jù)包最快的到達(dá)目的地,路由器需要選擇最優(yōu)的路徑轉(zhuǎn)發(fā)數(shù)據(jù)包。例如在常用的路由算法OSPF(開放式最短路徑優(yōu)先)中,路由器會使用經(jīng)典的Dijkstra算法計算最短路徑,然后盡量沿最短路徑轉(zhuǎn)發(fā)數(shù)據(jù)包。現(xiàn)在,若已知一個計算機網(wǎng)絡(luò)中各路由器間的連接情況,以及各個路由器的最大吞吐量(即每秒能轉(zhuǎn)發(fā)的數(shù)據(jù)包數(shù)量),假設(shè)所有數(shù)據(jù)包一定沿最短路徑轉(zhuǎn)發(fā),試計算從路由器1到路由器n的網(wǎng)絡(luò)的最大吞吐量。計算中忽略轉(zhuǎn)發(fā)及傳輸?shù)臅r間開銷,不考慮鏈路的帶寬限制,即認(rèn)為數(shù)據(jù)包可以瞬間通過網(wǎng)絡(luò)。路由器1到路由器n作為起點和終點,自身的吞吐量不用考慮,網(wǎng)絡(luò)上也不存在將1和n直接相連的鏈路。
Solution
裸題?
先求最短路看哪些邊會被用到,拆點跑一下網(wǎng)絡(luò)流
(雖然說了“會使用經(jīng)典的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; }?
轉(zhuǎn)載于:https://www.cnblogs.com/Zars19/p/6864102.html
總結(jié)
以上是生活随笔為你收集整理的[BZOJ 3931][CQOI2015]网络吞吐量(SPFA+网络流)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《漫画线性代数》读书笔记 用矩阵解方程组
- 下一篇: 《Maven官方文档》POM文件(一)