HDU - 4856 Tunnels 最短路bfs+状压dp

题目链接:点击查看

题意:n*n的图,给出m个隧道的起点和终点,问经过所有隧道所需要的最小时间,在隧道内不花时间,每个隧道只能走一次

题解:先预处理出每个隧道的终点到其他隧道的起点的最小距离,因为隧道只有15个,然后状压一下就可以了,主要要记录一个隧道的终点到其他的起点,因为起点或终点有可能会有一样的,我刚开始记录成终点到终点了,但是对于终点一样,起点不一样的隧道来说就会有多个值,就没法搞了,但是我们记录到起点的就可以了,即使终点不一样,那么花费的时间也是一样的。然后就是状压了                 dp[i][j] 表示以i隧道最后一个走,经过了j状态的最小距离

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
char mp[18][18];
int dis[18][(1<<15)+10],id[18][18],vis[18][18];
int n,m;
struct P{
	int x1,x2,y1,y2;
}a[18];
int flag;

int nex[4][2]={0,1,1,0,0,-1,-1,0};
struct node{
	int x,y,step,pos;
	node(){}
	node(int x_,int y_,int step_)
	{
		x=x_;y=y_;step=step_;;
	}
};
int num[18][18][18][18];
void init()
{
	memset(num,INF,sizeof(num));
	memset(dis,INF,sizeof(dis));
	memset(id,0,sizeof(id));
}
void DIJ(int x,int y)
{
	memset(vis,0,sizeof(vis));
	queue<node> q;
	node now;
	int xx,yy;
	int ll;
	q.push(node(x,y,0));
	vis[x][y]=1;
	while(!q.empty())
	{
		now=q.front();q.pop();
		if(id[now.x][now.y])
		{
			num[x][y][now.x][now.y]=now.step;
		}
		for(int i=0;i<4;i++)
		{
			xx=now.x+nex[i][0];
			yy=now.y+nex[i][1];
			if(xx<=0||xx>n||yy<=0||yy>n) continue;
			if(vis[xx][yy] || mp[xx][yy]=='#') continue;
			vis[xx][yy]=1;
			q.push(node(xx,yy,now.step+1));
		}
	}
}

int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		init();
		for(int i=1;i<=n;i++)
		{
			scanf("%s",mp[i]+1);
		}
		for(int i=1;i<=m;i++)
		{
			scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);
			id[a[i].x1][a[i].y1]=1;
		}
		for(int i=1;i<=m;i++)
		{
			DIJ(a[i].x2,a[i].y2);
		}
		int mm=1<<m;
		int pos;
		for(int i=1;i<mm;i++)
		{
			for(int j=1;j<=m;j++)
			{
				if((1<<(j-1)) & i)
				{
					pos=i^(1<<(j-1));
					if(pos==0) dis[j][i]=0;
					for(int k=1;k<=m;k++)
					{
						if((1<<(k-1)) & pos)
						{
							dis[j][i]=min(dis[j][i],dis[k][pos]+num[a[k].x2][a[k].y2][a[j].x1][a[j].y1]);

						}
							
					}
				}
			}
		}
		int ans=INF;
		for(int i=1;i<=m;i++) ans=min(ans,dis[i][mm-1]);
		if(ans==INF) ans=-1; 
		printf("%d\n",ans);//
	}
	return 0;
}
/*
5 4
.....
####.
.####
####.
.####
1 1 1 4
2 5 3 1
3 1 4 5
4 5 5 1
5 4
#...#
.###.
.....
.....
.....
1 2 1 4
1 3 2 1
2 5 2 1
2 1 3 1

*/

猜你喜欢

转载自blog.csdn.net/mmk27_word/article/details/89398167