题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3549
这道题应该算是一道模板的最大流了吧,可是网上看了很多C++的最大流模板,理解起来有困难,又很少有JAVA的最大流模板,于是找了个简单点的自己写了下,然后过了。
可能输入量有点大,Scanner输入是超时的,只能用io输入。
import java.io.*;
import java.util.*;
public class Main {
static int n,m;
static int map1[][]; //存储节点间的路径
static int pre[]; //储存增广路径
static boolean vis[]; //遍历bfs的时候判断节点是否用过
static int s,t; //s是源点,t是汇点
static boolean BFS() //找增广路径,不存在返回false
{
int cur; //储存当前的节点
LinkedList<Integer>q =new LinkedList<Integer>(); //一个队列,如果有路可走就加上
for(int j=0;j<pre.length;j++)pre[j]=0;
for(int j=0;j<vis.length;j++)vis[j]=false;
vis[s]=true;
q.offer(s);
while(!q.isEmpty()) //直到走不通时终止循环,返回false
{
cur=q.poll(); //取出当前节点,遍历是否有可行道路
if(cur==t) //走到汇点返回true
return true;
for(int i=1; i<=n; i++)
{
if(!vis[i] &&map1[cur][i]!=0)
{
q.offer(i);
pre[i]=cur;
vis[i]=true;
}
}
}
return false;
}
static int Max_flow()
{
int ans=0; //ans即为最大流
while(true) //寻找增广路,直到无法找到为止
{
if(!BFS())
return ans;
int Min=Integer.MAX_VALUE;
for(int i=t; i!=s; i=pre[i]) //找出这条增广路中最小的流量,为传输值
Min=Math.min(Min,map1[pre[i]][i]);
for(int i=t; i!=s; i=pre[i])
{
map1[pre[i]][i]-=Min; //正向路径减少,反向路径增加
map1[i][pre[i]]+=Min;
}
ans+=Min;
}
}//找增广路径上的最小流量
public static void main(String args[]) throws IOException{
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
map1=new int [1010][1010];
pre=new int[1010];
vis=new boolean[1010];
in.nextToken();
int T=(int) in.nval;
int v,u,c;
int k=1;
while(T--!=0)
{
in.nextToken();
n=(int) in.nval;
in.nextToken();
m=(int) in.nval;
for(int i=0;i<map1.length;i++){
for(int j=0;j<map1[i].length;j++){
map1[i][j]=0;
}
}
s=1;t=n;
while(m--!=0){
in.nextToken();
u=(int) in.nval;
in.nextToken();
v=(int) in.nval;
in.nextToken();
c=(int) in.nval;
map1[u][v]+=c;
}
System.out.println("Case "+(k++)+":"+" "+Max_flow());
// System.out.printf("Case %d: %d\n",k++,Max_flow());
}
}
}