这一题想了我很久,结果发现很智障。
原来是一个裸题啊。
先跑最大流,然后剩下的是一个残余网络,容易知道如果扩容,肯定在残余网络里面找路径,因为如果不在残余网络里面找路径,那么肯定就会多算,就相当于有流量不用。
在残余网络里面连边,流量无限,费用是扩容费用。
建立一个超级源点,向1点建一条边,流量为扩容大小,费用为0。跑一边MCMF即可。
#include
#include
#include
#include
#include
using namespace std;
int n,m,k;
struct edge{
int x,y,next,c,cos;
}s[50010];
int first[1010],d[1010],mmin[1010],last[1010],w[5010];
bool tf[1010];
int begin,end;
queue f;
int len=1;
void ins(int x,int y,int c,int cos){
len++;s[len]=(edge){x,y,first[x],c,cos};first[x]=len;
len++;s[len]=(edge){y,x,first[y],0,-cos};first[y]=len;
}
bool SPFA(int&flow,int&cost){
memset(tf,false,sizeof(tf));tf[begin]=true;
memset(d,63,sizeof(d));d[begin]=0;
mmin[begin]=1e9;
f.push(begin);
while(!f.empty()){
int x=f.front();f.pop();tf[x]=false;
for(int i=first[x];i!=0;i=s[i].next){
int y=s[i].y;
if(d[y]>d[x]+s[i].cos && s[i].c>0){
d[y]=d[x]+s[i].cos;mmin[y]=min(mmin[x],s[i].c);last[y]=i;
if(!tf[y]){
tf[y]=true;
f.push(y);
}
}
}
}
if(d[end]==d[end+1]) return false;
flow+=mmin[end];
cost+=mmin[end]*d[end];
int now=end;
while(now!=begin){
s[last[now]].c-=mmin[end];s[last[now]^1].c+=mmin[end];
now=s[last[now]].x;
}
return true;
}
void MCMF(int type){
int flow=0,cost=0;
while(SPFA(flow,cost));
if(type==1) printf("%d ",flow);
else printf("%d",cost);
}
int main(){
scanf("%d %d %d",&n,&m,&k);
begin=1,end=n;
int x,y,c;
for(int i=1;i<=m;i++){
scanf("%d %d %d %d",&x,&y,&c,&w[i]);
ins(x,y,c,0);
}
MCMF(1);
ins(begin=0,1,k,0);
for(int i=1;i<=m;i++) ins(s[2*i].x,s[2*i].y,1e9,w[i]);
MCMF(2);
}