传送门
网络流水题啊。
第一问直接放心跑最大流(本来还以为有什么
t
r
i
c
k
trick
trick)。
第二问就直接把原来的边
(
u
,
v
,
c
,
w
)
(u,v,c,w)
(u,v,c,w)变成
(
u
,
v
,
c
,
0
)
(u,v,c,0)
(u,v,c,0)和
(
u
,
v
,
i
n
f
,
w
)
(u,v,inf,w)
(u,v,inf,w),然后把
t
t
t拆点限制流量跑费用流就行了。
代码:
#include<bits/stdc++.h>
#define N 1005
#define M 10005
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
int s,t,n,m,k,first[N],cur[N],d[N],flow[N],pos[N],pred[N],cnt;
bool in[N];
struct Edge{int u,v,w,c;}tt[M];
struct edge{int v,next,w,c;}e[M<<1];
inline void addedge(int u,int v,int c,int w){e[++cnt].v=v,e[cnt].next=first[u],e[cnt].c=c,e[cnt].w=w,e[cnt].v=v,first[u]=cnt;}
inline void add(int u,int v,int c,int w){addedge(u,v,c,w),addedge(v,u,0,-w);}
inline void init(){memset(first,-1,sizeof(first)),cnt=-1,s=1,t=n;}
inline bool bfs(){
queue<int>q;
memset(d,-1,sizeof(d)),d[s]=0,q.push(s);
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=first[x];~i;i=e[i].next){
int v=e[i].v;
if(!e[i].c||~d[v])continue;
d[v]=d[x]+1,q.push(v);
}
}
return ~d[t];
}
inline int dfs(int x,int f){
if(!f||x==t)return f;
int flow=f;
for(int&i=cur[x];~i;i=e[i].next){
int v=e[i].v;
if(!flow)return f;
if(e[i].c&&d[v]==d[x]+1){
int tmp=dfs(v,min(flow,e[i].c));
if(!tmp)d[v]=-1;
e[i].c-=tmp,e[i^1].c+=tmp,flow-=tmp;
}
}
return f-flow;
}
inline bool spfa(){
queue<int>q;
memset(d,0x3f3f3f3f,sizeof(d)),memset(in,false,sizeof(in)),q.push(s),d[s]=0,in[s]=true,pred[t]=-1,flow[s]=0x3f3f3f3f;
while(!q.empty()){
int x=q.front();
q.pop(),in[x]=false;
for(int i=first[x];~i;i=e[i].next){
int v=e[i].v;
if(e[i].c&&d[v]>d[x]+e[i].w){
d[v]=d[x]+e[i].w,pred[v]=x,pos[v]=i,flow[v]=min(flow[x],e[i].c);
if(!in[v])in[v]=true,q.push(v);
}
}
}
return d[t]!=0x3f3f3f3f;
}
inline int dinic(){
int ret=0;
while(bfs()){
for(int i=1;i<=n;++i)cur[i]=first[i];
ret+=dfs(s,0x3f3f3f3f);
}
return ret;
}
inline int mcmf(){
int ret=0;
for(int w=t;spfa();w=t){
ret+=flow[t]*d[t];
while(w!=s)e[pos[w]].c-=flow[t],e[pos[w]^1].c+=flow[t],w=pred[w];
}
return ret;
}
int main(){
n=read(),m=read(),k=read(),init();
for(int i=1;i<=m;++i){
tt[i].u=read(),tt[i].v=read(),tt[i].c=read(),tt[i].w=read();
add(tt[i].u,tt[i].v,tt[i].c,0);
}
int tmp=dinic();
printf("%d ",tmp);
memset(first,-1,sizeof(first)),cnt=-1;
for(int i=1;i<=m;++i)add(tt[i].u,tt[i].v,tt[i].c,0),add(tt[i].u,tt[i].v,0x3f3f3f3f,tt[i].w);
add(n,n+1,k+tmp,0),t=n+1,printf("%d",mcmf());
return 0;
}