【[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);
}

浙公网安备 33010602011771号