HDU-3549

30 篇文章 1 订阅
26 篇文章 0 订阅

题目链接: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());
	    }
	}
}

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值