题解 POJ1734 【Sightseeing trip】

题目链接:Link

Problem

Solution

这题几乎是一个裸的无向图最小环,用一个数组记录最短路的中间节点是什么即可。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long LL;
const int maxn=305;
const int oo=0x3f3f3f3f;
int a[maxn][maxn],d[maxn][maxn],p[maxn][maxn];
int n,m,res;
vector<int> sol;
void dfs(int L,int R)
{
	if(p[L][R]==0) return;
	dfs(L,p[L][R]);
	sol.push_back(p[L][R]);
	dfs(p[L][R],R);
}
int main()
{
	#ifdef local
	freopen("pro.in","r",stdin);
	#endif
	scanf("%d%d",&n,&m);
	memset(a,0x3f,sizeof(a));
	for(int i=1;i<=n;i++) a[i][i]=0;
	for(int i=1;i<=m;i++)
	{
		int x,y,z; scanf("%d%d%d",&x,&y,&z);
		a[y][x]=a[x][y]=min(a[x][y],z);
	}
	memcpy(d,a,sizeof(a));
	res=oo;
	for(int k=1;k<=n;k++)
	{
		for(int i=1;i<k;i++)
			for(int j=i+1;j<k;j++)
				if((LL)d[i][j]+a[j][k]+a[k][i]<res)
				{
					res=d[i][j]+a[j][k]+a[k][i];
					sol.clear();
					sol.push_back(i);
					dfs(i,j);
					sol.push_back(j);
					sol.push_back(k);
				}
		for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(d[i][k]+d[k][j]<d[i][j])
		{
			d[i][j]=d[i][k]+d[k][j];
			p[i][j]=k;
		}
	}
	if(res==oo) { puts("No solution."); return 0; }
	for(int i=0;i<sol.size();i++) printf("%d ",sol[i]); puts("");
	return 0;
}
posted @ 2019-10-11 20:03  happyZYM  阅读(171)  评论(0编辑  收藏  举报