2018.10.10【CQOI2015】【BZOJ3931】【洛谷P3171】網路吞吐量(最短路)(最大流)
阿新 • • 發佈:2018-12-14
洛谷傳送門
解析:
好粗暴的最短路加最大流。。。
思路:
首先題目要求資料沿最短路傳遞,而且題目都說了,怎麼還有人寫,不怕被卡嗎?
於是,我們先求出最短路。
然後根據題目要求構建流網路圖,就是隻有在最短路樹裡面的邊才能夠加入流網路,並且容量設為。因為題目說了每條路徑的容量不限。
然後又是經典套路,點有容量怎麼辦?拆點啊,中間連點容量大小的邊。 直接最大流完事。
程式碼:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
inline int getint(){
re int num;
re char c;
while(!isdigit(c=gc()));num=c^48;
while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
return num;
}
cs int N=1003,M=101005;
cs int S=0,T=1002;
cs ll INF= 0x3f3f3f3f3f3f3f3f;
int last[N],nxt[M<<1],to[M<<1],ecnt=1;
ll cap[M<<1];
inline void addedge(int u,int v,ll val){
nxt[++ecnt]=last[u],last[u]=ecnt,to[ecnt]=v,cap[ecnt]=val;
nxt[++ecnt]=last[v],last[v]=ecnt,to[ecnt]=u,cap[ecnt]=0;
}
int lev[N],cur[N];
inline bool BFS(){
memset(lev, -1,sizeof lev);
queue<int> q;
q.push(S),lev[S]=0,cur[S]=last[S];
while(!q.empty()){
int u=q.front();
q.pop();
for(int re e=last[u],v=to[e];e;v=to[e=nxt[e]]){
if(cap[e]&&lev[v]==-1){
lev[v]=lev[u]+1;
if(v==T)return true;
cur[v]=last[v];
q.push(v);
}
}
}
return false;
}
inline ll Dinic(cs int &u,cs ll &flow){
if(u==T)return flow;
ll ans=0;
for(int &e=cur[u],v=to[e];e;v=to[e=nxt[e]]){
if(cap[e]&&lev[v]>lev[u]){
ll delta=Dinic(v,min(flow-ans,cap[e]));
if(delta){
cap[e]-=delta;
cap[e^1]+=delta;
ans+=delta;
if(ans==flow)return ans;
}
}
}
return ans;
}
inline ll maxflow(){
ll ans=0;
while(BFS())ans+=Dinic(S,INF);
return ans;
}
int c[N];
namespace SP{//Shortest_Path
int last[N],nxt[M<<1],to[M<<1],ecnt;
ll w[M<<1];
inline void Addedge(int u,int v,ll val){
nxt[++ecnt]=last[u],last[u]=ecnt,to[ecnt]=v,w[ecnt]=val;
nxt[++ecnt]=last[v],last[v]=ecnt,to[ecnt]=u,w[ecnt]=val;
}
ll dist[N];
bitset<N> vis;
inline void dijkstra(){
priority_queue<pair<ll,int>,vector<pair<ll,int> > ,greater<pair<ll,int> > > q;
vis.reset();
memset(dist,0x3f,sizeof dist);
q.push(make_pair(dist[1]=0,1));
while(!q.empty()){
int u=q.top().second;
q.pop();
if(vis[u])continue;
vis[u]=true;
for(int re e=last[u],v=to[e];e;v=to[e=nxt[e]])
if(dist[v]>dist[u]+w[e])q.push(make_pair(dist[v]=dist[u]+w[e],v));
}
}
}
using SP::Addedge;
using SP::dist;
int n,m;
signed main(){
n=getint(),m=getint();
for(int re i=1;i<=m;++i){
int u=getint(),v=getint(),d=getint();
Addedge(u,v,d);
}
SP::dijkstra();
for(int re u=1;u<=n;++u)
for(int re e=SP::last[u],v=SP::to[e];e;v=SP::to[e=SP::nxt[e]]){
if(dist[v]==dist[u]+SP::w[e])addedge(u+500,v,INF);
}
for(int re i=1;i<=n;++i){
int val=getint();
addedge(i,i+500,val);
}
addedge(S,1+500,INF);
addedge(n,T,INF);
cout<<maxflow();
return 0;
}