POJ 2914 Minimum Cut 无向图最小割SW算法

xiaoxiao2021-02-28  97

Minimum Cut Time Limit: 10000MS Memory Limit: 65536KTotal Submissions: 9996 Accepted: 4177Case Time Limit: 5000MS

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 A, B and C (0 ≤ A, B < N, A ≠ B, C > 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)

模板题。

复习网址:http://www.cnblogs.com/ylfdrib/archive/2010/08/17/1801784.html

在最大生成树中加入堆优化,复杂度可提升为O(n^2logn)。一般建议在稀疏图中加堆优化,稠密图就老老实实O(n^3)吧。

//无向图最小割SW Algorithm #include <cstdio> #include <iostream> #include <string.h> #include <string> #include <queue> #include <vector> #include <set> #include <algorithm> #include <math.h> #include <cmath> #include <bitset> #define mem0(a) memset(a,0,sizeof(a)) #define meminf(a) memset(a,0x3f,sizeof(a)) using namespace std; typedef long long ll; typedef long double ld; const int maxn=505,inf=0x3f3f3f3f; const ll llinf=0x3f3f3f3f3f3f3f3f; const ld pi=acos(-1.0L); int mp[maxn][maxn],dist[maxn]; int num,s,t,mcut; bool visit[maxn],com[maxn]; void prim(int n) { mem0(visit); mem0(dist); int i,j,to; s=t=-1; for (i=1;i<=n;i++) { int m=-1; for (j=1;j<=n;j++) { if (!com[j]&&!visit[j]&&dist[j]>m) { m=dist[j]; to=j; } } if (t==to) return; s=t;t=to; visit[to]=1; mcut=m; for (j=1;j<=n;j++) { if (!com[j]&&!visit[j]) { dist[j]+=mp[to][j]; } } } } int SW(int n) { int i,j,cas=n-1,ans=inf; mem0(com); while (cas--) { prim(n); ans=min(ans,mcut); if (ans==0) return 0; com[t]=1; for (j=1;j<=n;j++) { if (!com[j]) { mp[s][j]+=mp[t][j]; mp[j][s]+=mp[j][t]; } } } return ans; } int main() { int n,m,i,x,y,d; while (scanf("%d%d",&n,&m)!=EOF) { num=0; mem0(mp); for (i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&d); mp[x+1][y+1]+=d; mp[y+1][x+1]+=d; } int ans=SW(n); printf("%d\n",ans); } return 0; }

转载请注明原文地址: https://www.6miu.com/read-62766.html

最新回复(0)