hdu 3691 全局最小割模板题 + 一点学习记录

题目:

Nubulsa Expo

Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1230    Accepted Submission(s): 570


Problem Description
You may not hear about Nubulsa, an island country on the Pacific Ocean. Nubulsa is an undeveloped country and it is threatened by the rising of sea level. Scientists predict that Nubulsa will disappear by the year of 2012. Nubulsa government wants to host the 2011 Expo in their country so that even in the future, all the people in the world will remember that there was a country named “Nubulsa”.

As you know, the Expo garden is made up of many museums of different countries. In the Expo garden, there are a lot of bi-directional roads connecting those museums, and all museums are directly or indirectly connected with others. Each road has a tourist capacity which means the maximum number of people who can pass the road per second. 

Because Nubulsa is not a rich country and the ticket checking machine is very expensive, the government decides that there must be only one entrance and one exit. The president has already chosen a museum as the entrance of the whole Expo garden, and it’s the Expo chief directory Wuzula’s job to choose a museum as the exit.

Wuzula has been to the Shanghai Expo, and he was frightened by the tremendous “people mountain people sea” there. He wants to control the number of people in his Expo garden. So Wuzula wants to find a suitable museum as the exit so that the “max tourists flow” of the Expo garden is the minimum. If the “max tourist flow” is W, it means that when the Expo garden comes to “stable status”, the number of tourists who enter the entrance per second is at most W. When the Expo garden is in “stable status”, it means that the number of people in the Expo garden remains unchanged.

Because there are only some posters in every museum, so Wuzula assume that all tourists just keep walking and even when they come to a museum, they just walk through, never stay.
 

Input
There are several test cases, and the input ends with a line of “0 0 0”.

For each test case:

The first line contains three integers N, M and S, representing the number of the museums, the number of roads and the No. of the museum which is chosen as the entrance (all museums are numbered from 1 to N). For example, 5 5 1 means that there are 5 museums and 5 roads connecting them, and the No. 1 museum is the entrance.

The next M lines describe the roads. Each line contains three integers X, Y and K, representing the road connects museum X with museum Y directly and its tourist capacity is K.

Please note:

1<N<=300, 0<M<=50000, 0<S,X,Y<=N, 0<K<=1000000
 

Output
For each test case, print a line with only an integer W, representing the “max tourist flow” of the Expo garden if Wuzula makes the right choice.
 

Sample Input
  
  
5 5 1 1 2 5 2 4 6 1 3 7 3 4 3 5 1 10 0 0 0
 

Sample Output
  
  
8


分析:

题目给定一无向图和一个源点,汇点不确定,求源点到任一汇点最大流的最小值。由于汇点确定时最大流等于最小割,所以问题转化为汇点不定的最小最小割问题,即全局最小割问题。


最大流最小割定理:
https://wenku.baidu.com/view/d9c9b9220722192e4536f6e1.html

http://www.cnblogs.com/TreeDream/p/5929429.html】


割是指顶点的一种划分方式。割边集是指将源点和汇点划分为两个不连通的块的边的集合。在任何网络中,最大流的值等于最小割的容量(此时逆向割边流量为零,最小割容量即为正向割边流量)。即网络中允许的最大流量与割边集最小容量相等,两者都对应最细的管子集合。


对于一个网络流图G=(V,E),其中有源点s和汇点t,那么下面三个条件是等价的:
1. 流f是图G的最大流
2. 残留网络Gf不存在增广路
3. 对于G的某一个割(S,T),此时f = C(S,T)


代码:

源点给了用不到。

别人的板子拿来用

#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
const int maxn=310;
const int inf=0x3f3f3f3f;

int n,m,s,v[maxn],mat[maxn][maxn],dis[maxn];
bool vis[maxn];

int Stoer_Wagner(int n){
    int i, j;
    int res = inf;
    for (i = 0; i < n; i++)
        v[i] = i+1;//初始化第i个结点就是i
    while (n > 1)
    {
        int maxp = 1,prev = 0;
        for (i = 1; i < n; i++) //初始化到已圈集合的割大小,并找出最大距离的顶点
        {
            dis[v[i]] = mat[v[0]][v[i]];
            if (dis[v[i]] > dis[v[maxp]])
                maxp = i;
        }
        memset(vis, 0, sizeof(vis));
        vis[v[0]] = true;
        for (i = 1; i < n; i++)
        {
            if (i == n - 1)  //只剩最后一个没加入集合的点,更新最小割
            {
                res = min(res,dis[v[maxp]]);
                for (j = 0; j < n; j++)  //合并最后一个点以及推出它的集合中的点
                {
                    mat[v[prev]][v[j]] += mat[v[j]][v[maxp]];
                    mat[v[j]][v[prev]] = mat[v[prev]][v[j]];
                }
                v[maxp] = v[--n];//第maxp个节点去掉,第n个节点变成第maxp个
            }
            vis[v[maxp]] = true;
            prev = maxp;
            maxp = -1;
            for (j = 1; j < n; j++)
                if (!vis[v[j]])  //将上次求的maxp加入集合,合并与它相邻的边到割集
                {
                    dis[v[j]] += mat[v[prev]][v[j]];
                    if (maxp == -1 || dis[v[maxp]] < dis[v[j]])
                        maxp = j;
                }
        }
    }
    return res;
}

int main(){//904MS	1928K
    while (scanf("%d%d%d",&n,&m,&s),(n||m||s)){
        memset(mat,0,sizeof (mat));
        int x,y,z;
        while(m--){
            scanf("%d%d%d",&x,&y,&z);
            mat[x][y] += z;
            mat[y][x] += z;
        }
        printf("%d\n",Stoer_Wagner(n));
    }
}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值