第一问直接拍一个 dinic
第二问在第一问做完之后的残量网络上加上一些费用为 w[i] ,流量为 k 的边,新建一个源点,加一条费用为 0 ,流量为 k 的边连向原来的源点以限制流量。
主要是有些细节问题。
mdzz 我 spfa 队列开小 WA 了一次。。
#include
#include
#include
#define g getchar()
#define ll long long
#define inf 0x3f3f3f3f
#define rep(i,n) for(int i=1;i<=n;++i)
#define fi(i,j,k) for(int i=j;i<=k;++i)
#define di(i,j,k) for(int i=j;i>=k;--i)
using namespace std;
inline ll read(){
ll x=0,f=1;char ch=g;
for(;ch<'0'||ch>'9';ch=g)if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=g)x=x*10+ch-'0';
return x*f;
}
inline void out(ll x){
int a[25],wei=0;
if(x<0)putchar('-'),x=-x;
for(;x;x/=10)a[++wei]=x%10;
if(wei==0){puts("0");return;}
for(int j=wei;j>=1;--j)putchar('0'+a[j]);
putchar('\n');
}
struct re{int v,w,c,next;}ed[100005];struct re2{int x,y,w,c;}data[5005];
int pd[1005],dui[100005],head[1005],n,ans,ans2,dis[1005],from[1005],m,k,e=1;
inline void insert(int x,int y,int w,int c){ed[++e]=(re){y,w,c,head[x]};head[x]=e;}
void ins(int x,int y,int w){insert(x,y,w,0);insert(y,x,0,0);}
void ins(int x,int y,int w,int c){insert(x,y,w,c);insert(y,x,0,-c);}
bool jud[1005];
bool bfs(){
memset(pd,-1,sizeof(pd));
dui[1]=1;pd[1]=0;int tou=1,wei=1;
for(;tou<=wei;++tou){
int u=dui[tou];
for(int i=head[u];i;i=ed[i].next){
int v=ed[i].v;
if(pd[v]==-1&&ed[i].w){pd[v]=pd[u]+1;dui[++wei]=v;}
}
}
return pd[n]!=-1;
}
int dfs(int x,int fl){
int used=0;
if(x==n)return fl;
for(int i=head[x];i;i=ed[i].next){
int v=ed[i].v;
if(pd[x]+1==pd[v]&&ed[i].w){
int w=fl-used;
w=dfs(v,min(w,ed[i].w));
used+=w;ed[i].w-=w;ed[i^1].w+=w;
if(used==fl)return fl;
}
}
if(!used)pd[x]=-1;
return used;
}
void dinic(){for(;bfs();)ans+=dfs(1,inf);}
bool spfa(){
memset(pd,-1,sizeof(pd));
memset(jud,0,sizeof(jud));
memset(dis,inf,sizeof(dis));
dui[1]=0;pd[0]=0;dis[0]=0;jud[0]=1;
int tou=1,wei=1;
for(;tou<=wei;jud[dui[tou]]=0,++tou){
int u=dui[tou];
for(int i=head[u];i;i=ed[i].next){
int v=ed[i].v;
if(ed[i].w&&dis[v]>dis[u]+ed[i].c){
dis[v]=ed[i].c+dis[u];
from[v]=i;
if(!jud[v])dui[++wei]=v;
}
}
}
if(dis[n]==inf)return 0;
int fr=from[n],fl=inf;
for(;fr;fr=from[ed[fr^1].v])fl=min(fl,ed[fr].w);fr=from[n];
for(;fr;fr=from[ed[fr^1].v])ans2+=ed[fr].c*fl,ed[fr].w-=fl,ed[fr^1].w+=fl;
return 1;
}
void mcf(){for(;spfa(););}
int main(){
// freopen("1.in","r",stdin);
n=read();m=read();k=read();
rep(i,m){
int x=read(),y=read(),w=read(),c=read();
data[i]=(re2){x,y,w,c};
ins(x,y,w);
}
dinic();
printf("%d ",ans);
// rep(i,e){if(i%2)ed[i].w=0;}
// rep(i,e){if(i%2)ed[i^1].w+=ed[i].w,ed[i].w=0;}
ins(0,1,k,0);
rep(i,m)ins(data[i].x,data[i].y,k,data[i].c);
mcf();out(ans2);
return 0;
}