分析:
最小割,为了保证边数尽量少可以将容量设为Ci*1001+1。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
typedef long long LL;
int n,m,ecnt=-1,head[40];
int dep[40],cur[40];
LL maxflow,mincut;
std::queue<int> q;
struct Edge{
int to,nxt;
LL cap;
}e[2005];
inline void add_edge(int bg,int ed,LL ca){
ecnt++;
e[ecnt].to=ed;
e[ecnt].nxt=head[bg];
e[ecnt].cap=ca;
head[bg]=ecnt;
}
inline bool bfs(){
memset(dep,0x3f,sizeof dep);
for(int i=1;i<=n;i++) cur[i]=head[i];
while(!q.empty()) q.pop();
dep[1]=1;
q.push(1);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i!=-1;i=e[i].nxt){
int ver=e[i].to;
if(dep[ver]>1e9&&e[i].cap){
dep[ver]=dep[u]+1;
q.push(ver);
}
}
}
return dep[n]<1e9;
}
LL dfs(int x,LL pref){
if(x==n||!pref) return pref;
LL flow=0,temp;
for(int& i=cur[x];i!=-1;i=e[i].nxt){
int ver=e[i].to;
if(dep[ver]==dep[x]+1&&(temp=dfs(ver,std::min(pref,e[i].cap)))){
e[i].cap-=temp;
e[i^1].cap+=temp;
pref-=temp;
flow+=temp;
if(!pref) break;
}
}
return flow;
}
inline void dinic(){
while(bfs()) maxflow+=dfs(1,1e18);
}
int main(){
memset(head,-1,sizeof head);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v;LL w;
scanf("%d%d%lld",&u,&v,&w);
add_edge(u,v,1001*w+1);
add_edge(v,u,0);
}
dinic();
mincut=maxflow;
printf("%lld %lld\n",mincut/1001,mincut%1001);
return 0;
}