2011.07.26

         高中回家的孩纸们在群里讨论明天聚会的事,爷在悲催的码题解,嗷喵~好凄凉啊~

        让我也去杭电oj弄个Virtual Contest就叫我要回家~~~  


HDU3870 Catch the Theves

        题意:虽然题目给数据的方法非常含蓄还是掩盖不了其红果果的最小割本质。最小割就最大流呗~一看数据范围,400个点的密集图啊,吓到我了有木有~用直接最大流的方法又要TLE的啊~题解之后查了资料,才了我又土鳖了,建立S-T平面图,最短路也可以用来求最大流(囧)。

        解法:把原来的源点s=(1,1)和汇点t=(n,n)连一条边,这样就增加了一个s-t平面,对完成后的图作对偶图(标号对于这种网格图来说没压力啊~),去除对偶图上的s-t边后,对s到t求出最短路,即为所求最小割。(代码高仿,待修改……)

#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#define N 400*400
using namespace std;

int t,n,a[405][405];
int v,e,low[N],p[N],q[N],adj[N];
bool f[N];
struct Edge
{
	int v,w,next;
}edge[4*N];
void insert(int u,int v,int w)
{
	edge[e].v=v;edge[e].w=w;
	edge[e].next=adj[u];
	adj[u]=e++;
}
int spfa(int s)
{
	memset(f,0,sizeof(f));
	memset(low,0x7f,sizeof(low));
	//fill(low,low+n*n+5,999999999);
	int i,j,k,x,h=0,t=1;
	v=n*n+1;
	q[t]=s;
	low[s]=0;
	while(h!=t)
	{
		h=(h+1)%(v+1);
		x=q[h];
		f[x]=0;
		for(k=adj[x];k!=-1;k=edge[k].next)
		{
			i=edge[k].v;
			j=edge[k].w;
			if(j+low[x]<low[i])
			{
				low[i]=low[x]+j;
				if(!f[i])
				{
					f[i]=1;
					t=(t+1)%(v+1);
					q[t]=i;
				}
			}
		}
	}
	return low[n*n+1];
}
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		memset(adj,-1,sizeof(adj));
		int i,j;
		e=0;
		scanf("%d",&n);
		for(i=0;i<n;i++)
			for(j=0;j<n;j++)
				scanf("%d",&a[i][j]);
		n--;
		for(i=0;i<n;i++)
		{
			insert(0,i*n+1,a[i][0]);
			insert(0,(n-1)*n+i+1,a[n][i]);       //s平面,连边的时候是从下转向右的
			insert(i+1,n*n+1,a[0][i]);
			insert(i*n+n,n*n+1,a[i][n]);        //t平面
			for(j=0;j<n;j++)
			{
				if(j+1<n)
				{
					insert(i*n+j+1,i*n+j+2,a[i][j+1]);
					insert(i*n+j+2,i*n+j+1,a[i][j+1]);          //相邻平面
				}
				if(i+1<n)
				{
					insert(i*n+j+1,(i+1)*n+j+1,a[i+1][j]);
					insert((i+1)*n+j+1,i*n+j+1,a[i+1][j]);       //相邻平面
				}
			}
		}
		printf("%d\n",spfa(0));
	}
}


建立对偶图用最短路求原图最大流最小割:

详细参见集训队论文WC2008周冬,相当生动详细,该神牛不仅思维开阔独到,做ppt也是灰常厉害= =

传送门:http://wenku.baidu.com/view/5a7df375a417866fb84a8e54.html

少说几句:

1.应用该方法的要求是平面图,平面图是图中所有边都不相交形成"X"的图。

2.是对偶图的定义,我理解是对于平面图而言,平面上被边切割成独立不联通的区域作为对偶图的点,然后把代表相邻区域的点用一条边相连。该应用中,相邻区域拥有的同一条边的容量作为对偶图中边的长度,注意到这条边一定横跨过原图的对应边,其实这条边是对应了原图的一个割。那么容易理解该最小割的容量即是对偶图中的最短路。我对偶图理解和百度词条不同,如果有误请看到的朋友指正。这篇较好http://wenku.baidu.com/view/80864df14693daef5ef73d2b.html

3.关于此类题,若不是网格状题则对偶图顶点并不容易找出,这种方法还好用咩?



        嗷喵~日子都过不舒坦怎么有力气减肥呢= =

        人活着不是为了被理解吧……

        加油喵=( 0o0)= ~



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值