题意:
给出一个n个结点的无向图,每个结点有一个吞吐量;
规则是数据包传递一定按照最短路,求1到n的网络吞吐量;
题解:
正如黄学长所说,此题题意即题解;
但是还是有几点需要注意的;
最短路是dij还是spfa都可以,但是为了建图需要记录一下路径;
如果用链式前向星可以将所有用来更新的边存下来建图;
但是用vector或者邻接矩阵(不知道能不能过)存边就不能实现;
我是用一个vector数组上面挂链;
拓扑队列扫一遍加边,复杂度挺低就过了;
然后拆点建图就没什么说的了;
最短路和流量都要开long long,第一个和最后一个点的吞吐量不用计入;
代码:
#include<queue> #include<vector> #include<stdio.h> #include<string.h> #include<algorithm> #define pr pair<int,int> #define N 600 #define M 210000 using namespace std; typedef long long ll; queue<int>q; priority_queue<pr,vector<pr >,greater<pr > >poq; vector<int>to[N],pre[N]; vector<ll>val[N]; int head[N<<1],next[M],T[M],n,tot=1; ll dis[N<<1],flow[M]; bool vis[N]; void add(int x,int y,ll fl) { T[++tot]=y,next[tot]=head[x],head[x]=tot,flow[tot]=fl; T[++tot]=x,next[tot]=head[y],head[y]=tot,flow[tot]=0; } void dij() { memset(dis,0x3f,sizeof(dis)); dis[1]=0; poq.push(pr(0,1)); int x,y,i; while(!poq.empty()) { x=poq.top().second,poq.pop(); if(vis[x]) continue; vis[x]=1; for(i=0;i<to[x].size();i++) { if(!vis[y=to[x][i]]) { if(dis[y]>dis[x]+val[x][i]) { dis[y]=dis[x]+val[x][i]; poq.push(pr(dis[y],y)); pre[y].clear(); pre[y].push_back(x); } else if(dis[y]==dis[x]+val[x][i]) pre[y].push_back(x); } } } } bool bfs() { memset(dis,-1,sizeof(dis)); dis[3]=0; q.push(3); int x,y,i; while(!q.empty()) { x=q.front(),q.pop(); for(i=head[x];i;i=next[i]) { if(flow[i]>0&&dis[y=T[i]]<0) { dis[y]=dis[x]+1; q.push(y); } } } return dis[n<<1]>=0; } ll dfs(int x,ll k) { if(x==(n<<1)) return k; int y,i; ll j,ret=0; for(i=head[x];i;i=next[i]) { if(flow[i]>0&&dis[y=T[i]]==dis[x]+1) { j=dfs(y,min(flow[i],k-ret)); flow[i]-=j,flow[i^1]+=j; ret+=j; if(k==ret) return ret; } } return ret; } int main() { int m,i,j,k,x,y; ll v,ans; scanf("%d%d",&n,&m); for(i=1;i<=m;i++) { scanf("%d%d%lld",&x,&y,&v); to[x].push_back(y),val[x].push_back(v); to[y].push_back(x),val[y].push_back(v); } dij(); q.push(n); memset(vis,0,sizeof(vis)); while(!q.empty()) { x=q.front(),q.pop(); for(i=0;i<pre[x].size();i++) { y=pre[x][i]; add(y<<1|1,x<<1,0x3f3f3f3f3f3f3f3fll); if(!vis[y]) vis[y]=1,q.push(y); } } for(i=1;i<=n;i++) scanf("%lld",&v), add(i<<1,i<<1|1,v); ans=0; while(bfs()) ans+=dfs(3,0x3f3f3f3f3f3f3f3fll); printf("%lld",ans); return 0; }
原文地址:http://blog.csdn.net/ww140142/article/details/46627329