【最短路算法】聚会

一、题号605

  题目描述:小 S 想要从某地出发去同学的家中参加一个 party,但要有去有回。他想让所用的时间尽量的短。但他又想知道从不同的点出发, 来回的最短时间中最长的时间是多少,这个任务就交给了你。

  输入格式:第一行三个正整数n,m,k(n是节点个数,m是有向边的条数,k是参加聚会的)地点编号(1<=n<=1000,1<=m<=100,000)

  输出格式:一个整数,为不同的节点出发的最短时间中最长的时间。

  样例输入:

 

4 8 2
1 2 4
1 3 2
1 4 7
2 1 1
2 3 5
3 1 2
3 4 4
4 2 3

 

  样例输出:

10

 

二、思路分析:题意的意思是给定一有向图G(V,E)分别求所有点到一点k的最短路径与k到所有点的最短路径

     那么我们新建一个图,将原图的所有边反向,(所有点->k)就转换为了   (k->所有点)

  接下来这道题就是板子了分别对新旧图都跑一遍Dijs算法就行了

  三、Solution:

#include<bits/stdc++.h>
#define MAX 2000
#define Inf 0x3f3f3f3f
using namespace std;
typedef pair<int,int> PII;
struct Edge
{
	int to,w;
};
int n,m,k;
int dis1[MAX],dis2[MAX];
vector<Edge> G[MAX];
vector<Edge> opG[MAX];
void AddG(int from,int to,int w)
{
	G[from].push_back({to,w});
	opG[to].push_back({from,w});
}
void read()
{
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=m;i++)
	{
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		AddG(x,y,z);
	}
}
void Dijs1(int s)
{
	bool vis[MAX];
	memset(dis1,0x3f3f3f3f,sizeof(dis1));
	memset(vis,0,sizeof(vis));
	priority_queue<PII,vector<PII>,greater<PII> >heap;
	dis1[s]=0;
	heap.push({0,s});
	while(!heap.empty())
	{
		int x=heap.top().second;
		heap.pop();
		if(vis[x]) continue;
		vis[x]=1;
		for(int i=0;i<int(G[x].size());i++)
		{
			int y=G[x][i].to;
			int w=G[x][i].w;
			if(dis1[y]>dis1[x]+w)
			{
				dis1[y]=dis1[x]+w;
				heap.push({dis1[y],y});
			}
		}
	}
}
void Dijs2(int s)
{
	bool vis[MAX];
	memset(dis2,0x3f3f3f3f,sizeof(dis2));
	memset(vis,0,sizeof(vis));
	priority_queue<PII,vector<PII>,greater<PII> >heap;
	dis2[s]=0;
	heap.push({0,s});
	while(!heap.empty())
	{
		int x=heap.top().second;
		heap.pop();
		if(vis[x]) continue;
		vis[x]=1;
		for(int i=0;i<int(opG[x].size());i++)
		{
			int y=opG[x][i].to;
			int w=opG[x][i].w;
			if(dis2[y]>dis2[x]+w)
			{
				dis2[y]=dis2[x]+w;
				heap.push({dis2[y],y});
			}
		}
	}
}
int main()
{
	read();
	Dijs1(k);
	Dijs2(k);
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		if(dis1[i]==Inf) dis1[i]=0;
//		printf("%d ",dis1[i]);
		if(dis2[i]==Inf) dis2[i]=0;
//		printf("%d ",dis2[i]);
	}
	for(int i=1;i<=n;i++) ans=max(ans,dis1[i]+dis2[i]);
	printf("%d",ans);
}

  

posted @ 2022-06-30 21:00  正在加载90%  阅读(152)  评论(0)    收藏  举报