【BZOJ3345】Minimum Cut 全局最小割 【Stoer_Wagner算法】

题解:Stoer_Wagner算法。


Stoer_Wagner算法:不断进行缩点,在缩点过程中更新答案,类似于最小树形图。

缩点步骤:

写一棵苦力怕树:

http://blog.csdn.net/vmurder/article/details/42240877

(写最大生成树的肯定是污得不行)

然后会有一个点x最后才加入到A集合(vis==true),还有一个点y倒数第二个加入到A集合。

这时候把答案用dis[x]更新一下:ans=min(ans,dis[x]);

然后把x和y缩成一个点。


网上有些博客是把x和x的前驱缩成一个点,这是错的。

你写的都不是最大生成树,所有的边都对点x有贡献,怎么可能有前驱?!!


然后重复操作,直到整个图被缩成一个点。

返回ans。


细节:缩点时如何把边也缩一起?

对于入边,只需要一个并查集就可以了,

而对于出边,不妨用链表把并查集里的点全部存下来。

我的next数组和final数组就是链表、、


时间复杂度:

缩点时间复杂度等同于dijkstra/prim

然后会缩n次

加了堆优化O(n^2logn)

没加就是(n^3)

但是因为一些常数之类的问题,稠密图不要加堆优化。


代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 510
#define M 10500
#define inf 0x3f3f3f3f
using namespace std;
struct KSD
{
	int u,v,len,next;
}e[M<<1];
int head[N],cnt;
inline void add(int u,int v,int len)
{
	cnt++;
	e[cnt].v=v;
	e[cnt].len=len;
	e[cnt].next=head[u];
	head[u]=cnt;
}
int n,m;
int dis[N],pre[N];
int next[N],final[N];
bool vis[N];
int f[N];int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
inline void init()
{
	int i,j,k;
	memset(head,0,sizeof(head));
	for(cnt=1,i=1;i<=n;i++)f[i]=next[i]=final[i]=i;
}
inline int Stoer_Wagner()
{
	int ans=inf;
	int i,j,_n,r;
	int u,v,temp,lastu=0;
	for(_n=n;_n>1;_n--)
	{
		memset(dis,0,sizeof(dis));
		memset(vis,0,sizeof(vis));
		for(r=1;r<=_n;r++)
		{
			lastu=u;
			temp=-1;
			for(i=1;i<=n;i++)if(f[i]==i&&!vis[i])
			{
				if(temp<dis[i])temp=dis[i],u=i;
			}
			vis[u]=1;
			bool flag=0;
			for(j=u;;j=next[j])
			{
				if(j==final[u])flag=1;
				for(i=head[j];i;i=e[i].next)
				{
					v=find(e[i].v);
					if(v!=u)dis[v]+=e[i].len;
				}
				if(flag)break;
			}
		}
		ans=min(ans,dis[u]);
		f[u]=lastu;
		next[final[lastu]]=u;
		final[lastu]=final[u];
	}
	return ans;
}
int main()
{
	int i,j,k;
	int a,b,c;
	scanf("%d%d",&n,&m);
	init();
	while(m--)
	{
		scanf("%d%d%d",&a,&b,&c);
		add(a,b,c);
		add(b,a,c);
	}
	printf("%d\n",Stoer_Wagner());
	return 0;
}
</span>

这里给一组数据:

3 7
1 3 13
3 2 13
3 1 19
2 3 1
2 3 11
1 2 19
2 3 12


你可能感兴趣的:(cut,Minimum,全局最小割,BZOJ3345,Stoer_Wagner算法,苦力怕树)