看了一下很多人答案都是逆置矩阵。
我直接写了两个dijsktra函数,一个是k出去的,一个是回到k的。
设两个数组dis1,dis2。一个保存k->i最短的,一个保存i回来k的最短的。然后找到加起来最小的。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 1000+5
int e[maxn][maxn];//从i到j的路
int n,m,k;
int vis[maxn];
int dis1[maxn];//从i到k的最短路径
int dis2[maxn];//从k到i的最短路径
void dijkstral_to(int k)
{
/*找离k最近的那个点*/
/*i->k 去k那里*/
memset(vis,0,sizeof(vis));
int minn=1e9;
int index=-1;
int temp=n-1;
//初始化
for(int i=1;i<=n;i++)
{
dis1[i]=e[i][k];
}
vis[k]=1;
while(temp--)//n-1个点,一共要松弛n-1次
{
minn=1e9;
for(int i=1;i<=n;i++)
{
if(vis[i]!=1&&dis1[i]<minn)
{
minn=dis1[i];
index=i;
}
}
vis[index]=1;
for(int i=1;i<=n;i++)//从i到index这里最近距离的更新
{
if(!vis[i]&&e[i][index]+dis1[index]<dis1[i])
{
dis1[i]=e[i][index]+dis1[index];//可以通过中途某一个点到达
}
}
}
}
void dijkstra1_back(int k)//从k出发,回到本来的位置
{
memset(vis,0,sizeof(vis));
vis[k]=1;
for(int i=1;i<=n;i++)
{
dis2[i]=e[k][i];
}
//back from k
int minn=1e9;
int index=-1;
int temp=n-1;
while(temp--)//n-1个点,一共要松弛n-1次
{
minn=1e9;
for(int i=1;i<=n;i++)
{
if(vis[i]!=1&&dis2[i]<minn)
{
minn=dis2[i];
index=i;
}
}
vis[index]=1;
for(int i=1;i<=n;i++)//从i到index这里最近距离的更新
{
if(!vis[i]&&e[index][i]+dis2[index]<dis2[i])
{
dis2[i]=e[index][i]+dis2[index];//可以通过中途某一个点到达
}
}
}
}
int main()
{
int ans;
while(cin>>n>>m>>k)
{
ans=-1;
int a;
int b;
int c;
for(int i=1;i<=n;i++)//输入这里写错写成m找了一小时。。
{
for(int j=1;j<=n;j++)
{
if(i!=j)e[i][j]=1e9;
else e[i][j]=0;
}
}
for(int i=0;i<m;i++)
{
cin>>a>>b;
cin>>e[a][b];
}
dijkstral_to(k);
dijkstra1_back(k);
for(int i=1;i<=n;i++)
{
if(i==k) continue;
ans=max(ans,dis1[i]+dis2[i]);
}
cout<<ans<<endl;
}
return 0;
}