Flow Problem
Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 11558 Accepted Submission(s): 5471
For each test case, the first line contains two integers N and M, denoting the number of vertexes and edges in the graph. (2 <= N <= 15, 0 <= M <= 1000)
Next M lines, each line contains three integers X, Y and C, there is an edge from X to Y and the capacity of it is C. (1 <= X, Y <= N, 1 <= C <= 1000)
/************************************************
Desiner:hl
time:2015/11/02
Exe.Time:639MS
Exe.Memory:3184K
題解:裸最大流。做做練手速
不過還是小心。我一開始用了sap(S,V,V+1)導致答案出不來。
************************************************/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;
const int MAXN = 100010 ; //點數最大值
const int MAXM = 400010 ; //邊數最大值
const int INF = 0x3f3f3f3f;
int S,V,N,M;
struct Edge{
int to,next,cap,flow;
}edge[MAXM];//注意是MAXM
int tol;
int head[MAXN];
int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];
void init(){
tol = 0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w,int rw=0){
edge[tol].to = v;
edge[tol].cap = w;
edge[tol].next = head[u];
edge[tol].flow = 0;
head[u] = tol++;
edge[tol].to = u;
edge[tol].cap = rw;
edge[tol].next = head[v];
edge[tol].flow = 0;
head[v] = tol++;
}
//最大流開始
int sap(int start,int end,int N){
memset(gap,0,sizeof(gap));
memset(dep,0,sizeof(dep));
memcpy(cur,head,sizeof(head));
int u = start;
pre[u] = -1;
gap[0] = N;
int ans = 0;
while(dep[start] < N){
if(u==end){
int Min = INF;
for(int i=pre[u];i!= -1; i=pre[edge[i^1].to])
if(Min > edge[i].cap - edge[i].flow)
Min = edge[i].cap - edge[i].flow;
for(int i=pre[u];i!=-1;i=pre[edge[i^1].to]){
edge[i].flow += Min;
edge[i^1].flow -=Min;
}
u=start;
ans +=Min;
continue;
}
bool flag = false;
int v;
for(int i= cur[u];i!=-1;i=edge[i].next){
v=edge[i].to;
if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u]){
flag=true;
cur[u]=pre[v]=i;
break;
}
}
if(flag){
u=v;
continue;
}
int Min = N;
for(int i=head[u];i!= -1;i=edge[i].next)
if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min){
Min=dep[edge[i].to];
cur[u] = i;
}
gap[dep[u]]--;
if(!gap[dep[u]]) return ans;
dep[u] = Min +1;
gap[dep[u]]++;
if(u!=start) u = edge[pre[u]^1].to;
}
return ans;
}
//最大流結束
int build(){
int i,j,k,l,m,n,st,en,va;
init();
for(i=1;i<=M;i++){
scanf("%d%d%d",&st,&en,&va);
addedge(st,en,va);
}
int orz=sap(S,V,V);
return orz;
}
int main(){
int T;
int m,n,q,p;
int i,j,k,a,b,c;
int pisum;
scanf("%d",&T);
for(int cas=1;cas<=T;cas++){
scanf("%d%d",&N,&M);
S=1;
V=N;
printf("Case %d: %d\n",cas,build());
}
return 0;
}