【图论】新年好

【题目描述】
重庆城里有 n 个车站,m 条双向公路连接其中的某些车站。每两个车站最多用一条公路连接,从任何一个车站出发都可以经过一条或者多条公路到达其他车站,但不同的路径需要花费的时间可能不同。在一条路径上花费的时间等于路径上所有公路需要的时间之和。
佳佳的家在车站 111,他有五个亲戚,分别住在车站 a,b,c,d,e。过年了,他需要从自己的家出发,拜访每个亲戚(顺序任意),给他们送去节日的祝福。怎样走,才需要最少的时间?

【输入描述】
第一行:n,m 为车站数目和公路的数目。
第二行:a,b,c,d,e 为五个亲戚所在车站编号。
以下 m 行,每行三个整数 x,y,t ,为公路连接的两个车站编号和时间。

【输出描述】
输出仅一行,包含一个整数 T,为最少的总时间。

【样例输入】
6 6
2 3 4 5 6
1 2 8
2 3 3
3 4 4
4 5 5
5 6 2
1 6 7

【样例输出】
21

【思路】

最短路径水题…
从起点和每个亲戚家出发走一次最短路径,然后再通过深度优先搜索枚举每种走法的时间,取最小的那个。
代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#define re register
using namespace std;
int n,m,k,a[6];
struct node{
	int u,v,w;
}e[200001];
int f[50001];
int nxp[200001];
int cnt=0;
void add(int u,int v,int w)
{
	e[++cnt].u=u;
	e[cnt].v=v;
	e[cnt].w=w;
	nxp[cnt]=f[u];
	f[u]=cnt;
}
int d[50001][6];
bool vis[100001];
inline void spfa(int s,int t)
{
	queue<int>q;
	d[s][t]=0;
	memset(vis,0,sizeof(vis));
	q.push(s);
	vis[s]=1;
	while(!q.empty())
	{
		int u=q.front();q.pop();vis[u]=0;
		for(int re i=f[u];i;i=nxp[i])
		{
			int v=e[i].v;
			if(d[v][t]>d[u][t]+e[i].w)
			{
				d[v][t]=d[u][t]+e[i].w;
				if(!vis[v])
				{
					vis[v]=1;
					q.push(v);
				}
			}
		}
	}
}
int ans=0x7f7f7f7f;
inline void dfs(int u,int num,int y,int t)
{
	if(num==6)
	{
		ans=min(ans,y);
		return;
	}
	for(int re i=1;i<=5;i++)
	{
		if(!vis[a[i]])
		{
			vis[a[i]]=1;
			dfs(a[i],num+1,y+d[a[i]][t],i);
			vis[a[i]]=0;
		}
	}
}
int main()
{
	memset(d,127/3,sizeof(d));
	scanf("%d%d",&n,&m);
	a[0]=1;
	for(int re i=1;i<=5;i++)
		scanf("%d",&a[i]);
	for(int re i=1;i<=m;i++)
	{
		int u,v,r;
		scanf("%d%d%d",&u,&v,&r);
		add(u,v,r);add(v,u,r);
	}
	for(int re i=0;i<=5;i++)
		spfa(a[i],i);
	vis[1]=1;dfs(a[0],1,0,0);
	cout<<ans;
}


猜你喜欢

转载自blog.csdn.net/weixin_44111457/article/details/86695003