POJ-1161-Walls

POJ-1161-Walls

http://poj.org/problem?id=1161

对于空地i,j,若i,j相邻,则G[i][j]=1,即需要翻越一个城墙,否则G[i][j]=0,然后一遍floyd求出一个空地到另一个空地需要翻越的最少城墙数,最后枚举在哪个空地开Party就行了

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 99999999
#define N 250
int people[N],area[N][N],G[N][N],Dis[N];
int n,m,l;
int Min(int x,int y)
{
	return x<y?x:y;
}
void init()
{
	int i,j,k1,k2;
	scanf("%d%d%d",&m,&n,&l);
	for(i=1;i<=l;i++)
	{
		scanf("%d",&j);
		people[j]=i;
	}
	for(i=1;i<=m;i++)
	for(j=1;j<=m;j++)
	if(i!=j)
	G[i][j]=MAX;
	for(i=1;i<=m;i++)
	{
		scanf("%d",&area[i][0]);
		for(j=1;j<=area[i][0];j++)
		scanf("%d",&area[i][j]);
		area[i][area[i][0]+1]=area[i][1];
		for(j=1;j<=area[i][0];j++)  //判断两块空地是否相邻(只要有一条边重合)
		for(k1=1;k1<i;k1++)
		for(k2=1;k2<=area[k1][0];k2++)
		if(area[i][j]==area[k1][k2+1]&&area[i][j+1]==area[k1][k2])
		G[i][k1]=G[k1][i]=1;
	}

}
void floyd()
{
	int i,j,k;
	for(k=1;k<=m;k++)
	for(i=1;i<=m;i++)
	for(j=1;j<=m;j++)
	G[i][j]=Min(G[i][k]+G[k][j],G[i][j]);
}
void solve()
{
	int i,j,k,ans=MAX,best=0,sum;
	for(i=1;i<=m;i++)   //枚举在哪个空地办Party,Dist数组为每个人到当前枚举空地的最短距离
	{
		for(j=1;j<=l;j++)
		Dis[j]=MAX;
		for(j=1;j<=m;j++)
		for(k=1;k<=area[j][0];k++)
		if(people[area[j][k]]>0&&Dis[people[area[j][k]]]>G[i][j])
		Dis[people[area[j][k]]]=G[i][j];
		sum=0;
		for(j=1;j<=l;j++)
		sum+=Dis[j];
		if(sum<ans)
		{
			ans=sum;
			best=i;
		}
	}
	printf("%d\n",ans);
}
int main()
{
	init();
	floyd();
	solve();
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值