【[CQOI2015]网络吞吐量】最大流板题
不开longlong 毁一生。
luogu传送门:https://www.luogu.org/problemnew/show/P3171
首先先跑一个最短路上的所有最短路径,然后加入图中跑一次最大流就可以,还是比较裸的一道题。if(dis[x]+len[y]==dis[y])则这条路在最短路上。然后看每个点的吞吐量限制,我们将每个路由器拆成两个点来考虑,从一个点到这个点的镜像结点的容量为其限制就可以了,其他边直接连图,容量为inf。
然而这道题有坑点。。首先起始点没有吞吐量限制!要特判!还有就是要开longlong ,inf也要设大一些。int,一分都没有,,,
大概就是这样吧。。以下是sap代码
#include<bits/stdc++.h> using namespace std; long long n,m; long long owo,dis[300005],en[300005],nt[300005],la[300005],len[300005]; long long v[1005][1005]; long long fr[300005],to[300005],cd[300005]; long long cnt[1005]; void addedge(long long a,long long b,long long c) { en[++owo]=b; nt[owo]=la[a]; la[a]=owo; len[owo]=c; } long long dijdis[1005]; struct node { long long di,tt; }tmp; priority_queue<node>q; bool operator<(const node &aa,const node &bb) { return aa.di>bb.di; } void dijkstra(long long x) { long long ddd; for(long long i=1;i<=n;i++) dijdis[i]=0x3f3f3f3f; dijdis[1]=0; q.push((node){0,1}); while(q.size()) { x=q.top().tt; ddd=q.top().di; q.pop(); if(ddd!=dijdis[x]) continue; for(long long it=la[x];it;it=nt[it]) { if(dijdis[en[it]]>ddd+len[it]) { dijdis[en[it]]=ddd+len[it]; q.push((node){ddd+len[it],en[it]}); } } } } long long sap(long long x,long long flow) { if(x==2*n) return flow; long long delta=0,tmp; for(long long i=1;i<=2*n;i++) { if(v[x][i]&&dis[x]==dis[i]+1) { tmp=sap(i,min(flow-delta,v[x][i])); delta+=tmp; v[x][i]-=tmp; v[i][x]+=tmp; if(delta==flow||dis[1]>=2*n) return delta; } } if(dis[1]>=2*n) return delta; cnt[dis[x]]--; if(!cnt[dis[x]]) dis[1]=2*n; dis[x]++; cnt[dis[x]]++; return delta; } int main() { long long a,b,c; scanf("%lld%lld",&n,&m); for(long long i=1;i<=m;i++) { scanf("%lld%lld%lld",&a,&b,&c); addedge(a,b,c); addedge(b,a,c); fr[i]=a; to[i]=b; cd[i]=c; } dijkstra(1); long long x,y; for(long long i=1;i<=n;i++) { scanf("%lld",&x); if(i!=n&&i!=1)v[i][i+n]=x; else v[i][i+n]=1e14; } for(long long i=1;i<=m;i++) { if(dijdis[fr[i]]+cd[i]==dijdis[to[i]]) v[fr[i]+n][to[i]]=1e14; if(dijdis[to[i]]+cd[i]==dijdis[fr[i]]) v[to[i]+n][fr[i]]=1e14; } long long ans=0; while(dis[1]<2*n) { ans+=sap(1,1e14); } printf("%lld",ans); }