POJ 2914 Minimum Cut 最小割图论

POJ 2914 Minimum Cut 最小割图论

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

Description

Given an undirected graph, in which two vertices can be connected by multiple edges, what is the size of the minimum cut of the graph? i.e. how many edges must be removed at least to disconnect the graph into two subgraphs?

Input

Input contains multiple test cases. Each test case starts with two integers N and M (2 ≤ N ≤ 500, 0 ≤ M ≤ N × (N − 1) ⁄ 2) in one line, where N is the number of vertices. Following are M lines, each line contains M integers AB and C (0 ≤ AB < NA ≠ BC > 0), meaning that there C edges connecting vertices A and B.

Output

There is only one line for each test case, which contains the size of the minimum cut of the graph. If the graph is disconnected, print 0.

Sample Input

3 3
0 1 1
1 2 1
2 0 1
4 3
0 1 1
1 2 1
2 3 1
8 14
0 1 1
0 2 1
0 3 1
1 2 1
1 3 1
2 3 1
4 5 1
4 6 1
4 7 1
5 6 1
5 7 1
6 7 1
4 0 1
7 3 1

Sample Output

2
1
2

Source

Baidu Star 2006 Semifinal 

Wang, Ying (Originator) 

Chen, Shixi (Test cases)

本题是06年百度之星半决赛的题目,图论的最小割问题。算是图论高级内容吧。

Stoer Wager算法,当中的难点是:

1 逐条边查找最大的边的权值-过程有点想Prime算法,只是实际上不是Prime算法,由于目的并非最大生成树,而是须要把一个顶点的全部边都加起来。把这些边去掉,就是这个顶点的割点值了。那么就须要遍历整个图,到了最后一个节点才干保证是找到了这个节点的全部边。

2 缩点:所谓缩点就是把最后一个节点去掉,同一时候保留其边值信息,实际就是保留这个顶点的和其它顶点相连的最小边值。

比較难理解的,一般写这个题解报告的博客,一个是要么直接抄模板了。二是要么没有讲解;三个是有了几句讲解了。结果都没理解好,甚至错误;

也是非常难说清楚的一个题目,看看我具体凝视的程序吧。

#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <algorithm>
using namespace std;

const int MAX_N = 501;
int gra[MAX_N][MAX_N];//矩阵表示图

bool shrinkedVertices[MAX_N];//标志那些顶点已经被缩点了
bool vis[MAX_N];//标志当前那些节点已经訪问了
int dis[MAX_N];//记录最大距离
int lastSec, last;//记录每次最后cut边的两个顶点
int getLastCut(int leftVertices, int n)//每次计算剩下多少没缩点的顶点计算就可以
{
	fill(dis, dis+n, 0);
	fill(vis, vis+n, false);
	int curVer = 0;//curVer代表当前选取的顶点,初始为选取0顶点
	lastSec = last = 0;

	//循环的主要作用的把一个顶点的全部边都加起来。仅仅有在最后一次选择的时候才干确保最后一个顶点的全部边都加起来了。
	for (int i = 1; i < leftVertices; i++)
	{//操作的是边。边比顶点少1的,故此i从1開始,不是从0開始
		for (int v = 1; v < n; v++)
		{//0顶点已经最先选择了,故此v从1開始,不是从0開始
			if (!vis[v] && !shrinkedVertices[v]) dis[v] += gra[v][curVer];
		}//主要是把一个顶点的全部边都加起来
		int maxCut = 0;
		//选取当前最大的割边。未到最后一点。不能保证是真正的割边
		for (int v = 1; v < n; v++)
		{
			if (!vis[v] && !shrinkedVertices[v] && dis[v] > maxCut)
			{
				maxCut = dis[v];
				curVer = v;
			}
		}
		if (!maxCut) return 0;//本来就是分隔图,割边能够为零了。

vis[curVer] = true; lastSec = last; last = curVer;//逐次保存最后两个顶点 } return dis[last];}int Stoer_Wagner(int n){ fill(shrinkedVertices, shrinkedVertices+n, false); int minCut = INT_MAX; for (int i = n; i > 1; i--) { minCut = min(minCut, getLastCut(i, n)); if (!minCut) return 0; shrinkedVertices[last] = true; for (int v = 0; v < n; v++) { if (!shrinkedVertices[v]) gra[lastSec][v] = gra[v][lastSec] += min(gra[v][last], gra[last][lastSec]);//事实上缩点就是保留当中一段边,须要保留最小值边,确保是最小割。 } } return minCut == INT_MAX? 0 : minCut;}int main(){ int N, M, u, v, w; while (~scanf("%d %d", &N, &M)) { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { gra[i][j] = 0; } } for (int i = 0; i < M; i++) { scanf("%d %d %d", &u, &v, &w); gra[u][v] = gra[v][u] += w; } printf("%d\n", Stoer_Wagner(N)); } return 0;}

只是上面程序的效率不高。那么能够优化一下。优化的主要方法是,利用一个数组保存好剩下的顶点,那么缩点的时候直接删除这个顶点。就不用下一次还须要遍历推断这个顶点。

这样优化了常数项,实际执行时间快了2到3倍左右,效果非常好。

#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <algorithm>
using namespace std;

const int MAX_N = 501;
int gra[MAX_N][MAX_N];
int vps[MAX_N];
bool vis[MAX_N];
int dis[MAX_N];
int last, sec;

int getLastCut(int V)
{
	fill(vis, vis+V, false);
	fill(dis, dis+V, 0);
	last = sec = 0;
	int id = 0;
	for (int i = 1; i < V; i++)
	{
		int v = vps[id];
		for (int j = 1; j < V; j++)
		{
			if (!vis[j]) dis[j] += gra[v][vps[j]];
		}
		int m = 0;
		for (int j = 1; j < V; j++)
		{
			if (!vis[j] && m < dis[j]) m = dis[j], id = j;
		}
		if (!m) return 0;
		vis[id] = true;
		sec = last; last = vps[id];
	}
	swap(vps[id], vps[V-1]);
	return dis[id];
}

int Stoer_wagner(int n)
{
	for (int i = 0; i < n; i++) vps[i] = i;
	int minCut = INT_MAX;
	for (int V = n; V > 1; V--)
	{
		minCut = min(minCut, getLastCut(V));
		if (!minCut) return 0;
		for (int i = 0; i < V; i++)
		{
			int v = vps[i];
			gra[v][sec] = gra[sec][v] += min(gra[v][last], gra[last][sec]);
		}
	}
	return minCut == INT_MAX? 0 : minCut;
}

int main()
{
	int Ver, Edge, u, v, w;
	while (~scanf("%d %d", &Ver, &Edge))
	{
		for (int i = 0; i < Ver; i++)
			for (int j = 0; j < Ver; j++)
				gra[i][j] = 0;

		for (int i = 0; i < Edge; i++)
		{
			scanf("%d %d %d", &u, &v, &w);
			gra[u][v] = gra[v][u] += w;
		}
		printf("%d\n", Stoer_wagner(Ver));
	}
	return 0;
}

版权声明:笔者靖心脏,景空间地址:http://blog.csdn.net/kenden23/。只有经过作者同意转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116766.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • c程序中整形变量只能存放整数实型变量只能存放浮点数_c语言合法的实型常量

    c程序中整形变量只能存放整数实型变量只能存放浮点数_c语言合法的实型常量vb中,以下变量类型1,数字型变量(numeric)2,字符串型变量(string)3,日期型变量(date)4,对象型变量(object)5,变体型变量(variant)这几个vb变量类型中,最最主要的就是前面两个,数字型变量和字符串型变量.意思很简单,数字型可以用来存放数字,字符串型存放文本.下面就来详细介绍这几种变量.1.数字型数字型变量有多种类型,在咱们的vb里,有3中数字数据类型1;整形…

    2025年7月24日
    5
  • python3安装后没有pip_解决Centos7安装python3后pip工具无法使用「建议收藏」

    python3安装后没有pip_解决Centos7安装python3后pip工具无法使用「建议收藏」问题描述:Centos7安装python3,正常流程全部配置完成,python3,pip3的软链接也建立了但是python3可以正常使用,而pip3报错,无法找到文件或目录解决方法:which命令:查找python的路径type命令:也是查找python的路径发现两次命令查询的结果并不一致使用hash-r清除Linux下哈希表中所有缓存,下次再typepython就会去系统环境变量中查找路径,…

    2025年11月26日
    4
  • vue.js和jquery的区别_人和人类的区别是什么

    vue.js和jquery的区别_人和人类的区别是什么jquery:曾经是前端最流行的js库。vue:是一个精简的MVVM,从技术角度讲。vue.js专注于MVVM模型的ViewModel层,它通过双向数据绑定把view和Model层连接起来,通过对数据的操作就可以完成对页面视图的渲染。vue和jQuery区别:①vue和jQuery对比jquery是使用选择器()选取DOM对象,对其进行赋值、取值、事件绑定等操作,其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和界面是在一起的。②比如需要获取label标签的内..

    2022年10月15日
    5
  • 推荐几个长期有效的免费服务器和免费vps游戏服务器亲测再用

    推荐几个长期有效的免费服务器和免费vps游戏服务器亲测再用对于新手,搞网络购买现有的服务器和VPS成本太高!这里我长期测试筛选了几个长期有效好用的服务器!(当然免费虽好请勿滥用)1.FREEWHA这个服务器已经存在10几年了,好用谷歌收录也可以。提供1.5g空间免费流量,SSL申请免费空间很少有提供SSL的!这个空间的缺点就是无法上传大文件,最好用FTP上传。如果你做博客网站,选择SQLIVE数据库的最好。比如;ZBLOG的网站程序.2.Freehosting一个非常稳定的免费空间,提供10G空间和无限流量。这个空间其他功能都需要购买,数据库链接有流量限制

    2022年10月5日
    4
  • echarts图表在Tab页中width: 100%失效导致的第一个Tab页之后的Tab页图表不能正常显示的问题

    echarts图表在Tab页中width: 100%失效导致的第一个Tab页之后的Tab页图表不能正常显示的问题

    2021年11月22日
    50
  • C++ 读写TXT文件

    C++ 读写TXT文件 一、文件的输入输出二、从txt文件中读取二维数组(int以及string)三、从txt文件读取的数据存到struct中 参考博客:https://blog.csdn.net/u013749068/article/details/78761553     http://www.cnblogs.com/helinsen/archive/2012/07/26/2609…

    2022年5月5日
    61

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号