100%的数据中,N<=1000,M<=5000,K<=10
解题思路:第一问就是最大流,然后第二问,可以对在建m条边,只是产生费用,再来一个源点,到一的容量为K。跑一边费用流。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int n,m,k,len,ans;
int from[21000],to[21000],cc[21000],ww[21000],next[21000];
int h[1100];
int dis[1100];
int q[1000000];
bool og[1100];
int pre[1100];
int x[5100],y[5100],c[5100],w[5100];
inline int read()
{
char y; int x=0,f=1; y=getchar();
while (y<'0' || y>'9') {if (y=='-') f=-1; y=getchar();}
while (y>='0' && y<='9') {x=x*10+int(y)-48; y=getchar();}
return x*f;
}
void insert(int x,int y,int c,int w)
{
++len;
from[len]=x; to[len]=y; cc[len]=c; ww[len]=w; next[len]=h[x]; h[x]=len;
}
int dicnic(int sum,int now)
{
if (now==n) return sum;
int u=h[now]; int sug=0;
while (u!=0)
{
if (cc[u]>0 && dis[now]+1==dis[to[u]])
{
int s=dicnic(min(cc[u],sum-sug),to[u]);
if (s>0)
{
sug+=s;
cc[u]-=s; cc[u^1]+=s;
if (sug==sum) return sum;
}
}
u=next[u];
}
if (sug==0) dis[now]=-1;
return sug;
}
bool bfs()
{
memset(dis,-1,sizeof(dis));
dis[1]=1; int tail=0,head=0; ++tail; q[tail]=1;
while (head<tail)
{
++head;
int u=h[q[head]];
while (u!=0)
{
if (cc[u]>0 && dis[to[u]]==-1)
{
dis[to[u]]=dis[q[head]]+1;
++tail; q[tail]=to[u];
}
u=next[u];
}
}
if (dis[n]!=-1) return true; else return false;
}
bool spfa()
{
memset(dis,0x7e,sizeof(dis));
memset(og,true,sizeof(og));
og[0]=false;
dis[0]=0; int tail=1,head=0; q[tail]=0;
while (head<tail)
{
++head;
int u=h[q[head]];
while (u!=0)
{
if (cc[u]>0 && dis[to[u]]>dis[q[head]]+ww[u])
{
pre[to[u]]=u;
dis[to[u]]=dis[q[head]]+ww[u];
if (og[to[u]])
{
og[to[u]]=false;
++tail; q[tail]=to[u];
}
}
u=next[u];
}
og[q[head]]=true;
}
if (dis[n]<1000000) return true;else return false;
}
void mcf()
{
int now=n; int zan=0x7fffffff;
while (now!=0)
{
zan=min(zan,cc[pre[now]]);
now=from[pre[now]];
}
now=n;
while (now!=0)
{
cc[pre[now]]-=zan; cc[pre[now]^1]+=zan;
ans+=zan*ww[pre[now]];
now=from[pre[now]];
}
}
int main()
{
n=read(); m=read(); k=read();
len=1;
for (int i=1;i<=m;++i)
{
x[i]=read(); y[i]=read(); c[i]=read(); w[i]=read();
insert(x[i],y[i],c[i],0); insert(y[i],x[i],0,0);
}
int sum=0;
while (bfs())
{
sum+=dicnic(0x7fffffff,1);
}
printf("%d ",sum);
insert(0,1,k,0); insert(1,0,-k,0);
for (int i=1;i<=m;++i)
{
insert(x[i],y[i],k,w[i]); insert(y[i],x[i],0,-w[i]);
}
ans=0;
while (spfa())
{
mcf();
}
printf("%d",ans);
}