poj3268-Silver Cow Party(dijsktra算法)

看了一下很多人答案都是逆置矩阵。
我直接写了两个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;
}
发布了16 篇原创文章 · 获赞 1 · 访问量 268

猜你喜欢

转载自blog.csdn.net/weixin_44254608/article/details/104665636