题意:给n个顶点和m条边的有向图,输出每一个顶点到顶点X和顶点X到每一个顶点的最短路径之和最大的那个数。
思路:从顶点X到每一个顶点的最短路径不难想到直接套用Dijkstra算法即可得到,难的是每一个顶点到X的最短路,这里有一个巧妙的就是将原来的有向图各条边取反向,再在X做一次单源最短路,即为每个点到X点的最短路径,两者相加然后取最大即可
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <set>
#include <ctime>
#include <cmath>
#include <cctype>
using namespace std;
#define maxn 1005
#define LL long long
const int INF = 1<<29;
int cas=1,T;
int mapp[maxn][maxn];
int n,m,x;
int dijkstra()
{
int mins,v;
int d[maxn];
int dd[maxn];
int vis[maxn];
for (int i = 1;i<=n;i++)
{
vis[i]=0;
d[i]=mapp[x][i]; //从x点出发
dd[i]=mapp[i][x];
}
for (int i = 1;i<=n;i++)
{
mins = INF;
for (int j = 1;j<=n;j++)
if (!vis[j] && d[j] < mins)
{
v=j;
mins = d[j];
}
vis[v]=1;
for (int j = 1;j<=n;j++)
if (!vis[j] && d[j] > mapp[v][j]+d[v])
d[j]=mapp[v][j]+d[v];
}
memset(vis,0,sizeof(vis));
for (int i = 1;i<=n;i++)
{
mins = INF;
for (int j = 1;j<=n;j++)
if (!vis[j] && dd[j] < mins)
{
v=j;
mins = dd[j];
}
vis[v]=1;
for (int j = 1;j<=n;j++)
if (!vis[j] && dd[j] > mapp[j][v]+dd[v])
dd[j] = mapp[j][v]+dd[v];
}
int ans = -1;
for (int i = 1;i<=n;i++)
ans = max(ans,d[i]+dd[i]);
return ans;
}
int main()
{
scanf("%d%d%d",&n,&m,&x);
for (int i = 1;i<=n;i++)
for (int j = 1;j<=n;j++)
{
if (i!=j)
mapp[i][j]=INF;
else
mapp[i][j]=0;
}
for (int i = 1;i<=m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
mapp[a][b]=c;
}
printf("%d\n",dijkstra());
//freopen("in","r",stdin);
//scanf("%d",&T);
//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
return 0;
}
题目
本文介绍了一种利用Dijkstra算法解决特定场景下最短路径问题的方法。具体来说,该问题涉及寻找从各个农场到聚会地点及返回的最大总行走时间。通过两次应用Dijkstra算法——一次用于寻找从聚会地点到所有农场的最短路径,另一次用于寻找从所有农场到聚会地点的最短路径——可以有效地找到解决方案。
&spm=1001.2101.3001.5002&articleId=50570582&d=1&t=3&u=736fffd6bcbf4b87a28af4ba52056432)

被折叠的 条评论
为什么被折叠?



