题意:
给出一个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;
}