网络流.
AC code:
#include <cstdio>
const int N=100010;
const int M=1000010;
const int INF=1<<28;
int n,m,cnt=1,S,T,he,ta,mcf,mcost;
int head[N],Q[N],mina[N],minf[N],num[N];
bool inq[N];
struct Edge{
int u,v,f,a,next;
Edge() {}
Edge(int u,int v,int f,int a,int next):u(u),v(v),f(f),a(a),next(next) {}
}E[N];
int Min(int x,int y){
return x<y?x:y;
}
void addedge(int u,int v,int c,int a){
E[++cnt]=Edge(u,v,c,a,head[u]);
E[++cnt]=Edge(v,u,0,-a,head[v]);
head[u]=cnt-1;head[v]=cnt;
}
void read(){
scanf("%d%d",&n,&m);
S=1;T=n;
for(int i=2;i<n;i++) addedge(i,i+n,1,0);
for(int i=1;i<=m;i++){
int u,v,a;
scanf("%d%d%d",&u,&v,&a);
if(u==S) addedge(S,v,1,a);
else addedge(u+n,v,1,a);
}
}
bool SPFA(){
he=0;ta=1;Q[0]=S;minf[S]=INF;
for(int i=2;i<=n*2-1;i++) mina[i]=minf[i]=INF;
while(he!=ta){
int x=Q[he++];if(he==1001) he=0;
inq[x]=0;
for(int i=head[x];i;i=E[i].next){
Edge e=E[i];
if((!e.f)||mina[x]+e.a>=mina[e.v]) continue;
num[e.v]=i;
mina[e.v]=mina[x]+e.a;
minf[e.v]=Min(minf[x],e.f);
if(!inq[e.v]){
inq[e.v]=1;
Q[ta++]=e.v;if(ta==1001) ta=0;
}
}
}
if(minf[T]==INF) return 0;
mcf+=minf[T];mcost+=mina[T]*minf[T];
for(int i=T;i!=S;i=E[num[i]].u){
E[num[i]].f-=minf[T];
E[num[i]^1].f+=minf[T];
}
return 1;
}
int main(){
read();
while(SPFA());
printf("%d %d",mcf,mcost);
return 0;
}