pku 1273_Drainage Ditches 最大流问题

经典网络流问题,使用Ford Fulkson算法。


思路大概是:求排水沟网络中的最大排水量。

                  从源点开始,每次寻找一条增广路径,更新一次,再重新找增广路径……直到没有为止。即每次寻找一条由源点到汇点的路径;

                  把路径全部找完之后,剩余网络是最优网络,即能实现最大流。

                  寻找增广路径时我使用了广搜,这是比较容易实现的过程。

 

详细代码:

Source Code

Problem: 1273 User: moxiaomomo
Memory: 332K Time: 0MS
Language: C++ Result: Accepted
  • Source Code
  • Source Code
    
    Problem: 1273		User: moxiaomomo
    Memory: 332K		Time: 0MS
    Language: C++		Result: Accepted
    Source Code
    #include<iostream>
    using namespace std;
    
    int N,M;
    
    int cost[205][205],r;
    int Min[205],pre[205];    
    bool visit[205];   //搜索标记
    
    int bfs()
    {
    	int q[205],start = 0,end = 0;
    	memset(visit,false,sizeof(visit));
    	q[0] = 1;         //以n点为搜索起点
    	visit[1]=true;
    	Min[1]=10000005;
    	while(start<=end)     //搜索的最后一个点将是n+1
    	{
    		int t=q[start];      //下面进行点t的广搜
    		for(int i=1;i<=M;++i)
    		{
    			if(!visit[i]&&cost[t][i]!=0)
    			{   //Min[t],最小值传递;如果前向节点记录的值比当前的边的值要大,则...
    				Min[i]=(Min[t]<cost[t][i])? Min[t] : cost[t][i];
    				//Min[t]的作用是记录路径中权值最小的边
    				pre[i]=t;         //i的前向节点为t,在搜索过程中不断更新
    				if(i==M)
    				{return Min[M];}     //搜索完毕
    				visit[i]=true;
    				q[++end]=i;     //将i并入已搜索的集合
    			}
    		}
    		start++;      //进行下一个点的广搜
    	}
    	if (visit[M])      //如果最后一个点被搜索到,则说明存在增广路径
           return Min[M];
        else return -1 ;
    }
    
    void Ford_Fulkerson()
    {
    	int max=0,t,pre_t;
    	while((r = bfs()) != -1) //存在增广路径
    	{
    		max+=r; //最后max的值将是最大流的值
    		t=M;
    		while(t!=1)
    		{
    			pre_t=pre[t]; //找出前向点
    			cost[pre_t][t]-=r;    //前向路径值减一
    			cost[t][pre_t]+=r;    //后向路径值加一
    			t=pre_t;      //更新前向点
    		}
    	}
    	printf("%d/n",max);
    }
    
    int main()
    {
    	int k,x,y;
    	while(scanf ("%d%d",&N,&M) != EOF)
    	{
    		memset(cost,0,sizeof(cost));
    
    		for(int i=0;i<N;++i)
    		{
    			scanf("%d%d%d",&x,&y,&k);
    			cost[x][y]+=k;
    		}
    
    		Ford_Fulkerson();
    	}
    
        return 0;
    }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值