71.双向最短路径:聚会

1992 聚会

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 黄金 Gold
题目描述 Description

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

输入描述 Input Description

第一行三个正整数n, m, k(n是节点个数,m是有向边的条数,k是参加聚会的地点
编号)( 1 ≤ n ≤ 1000 ,1 ≤ m ≤ 100,000)
第二行..m + 1行每行3个整数x,y,w 代表从x到y需要花w的时间 0

输出描述 Output Description

输出从不同的节点出发的最短时间中最长的时间

样例输入 Sample Input

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

样例输出 Sample Output

10

数据范围及提示 Data Size & Hint

分类标签 Tags 点此展开 

思路:跑两边地杰斯特拉,一次正着跑,一次倒跑(把所有的边都反向存起来)
代码:

#include

using namespace std;

#include

#include

struct Edge{

       int u,v,w,next;

};

#include

Edge edge[100001<<1],edge1[100001<<1];//注意边表一定要开到n*n的大小,才可以不越界

const int INF=0x7fffffff; // 赋值最大值,0x7(再加上七个f)就是无限数,这个题虽然w=100,但是边的数目很多时,仍会超过999999,所以要赋这个数

int head[100001],visit[100001],head1[100001],visit1[100001];

int dis[100001],dis1[100001],dis2[100001];

int n,m,k;

void input()

{

       scanf("%d%d%d",&n,&m,&k);///n ge dian

       for(int i=1;i<=n;++i)

       {

         dis[i]=INF;

      dis1[i]=INF;

       }

       int t=0;

       for(int i=1;i<=n;++i)

         for(int j=1;j<=n;++j)

          {

            edge[++t].w=INF;

            edge1[t].w=INF;

          }

       for(int i=1;i<=m;++i)

       {

              scanf("%d%d%d",&edge[i].v,&edge[i].u,&edge[i].w);

              edge[i].next=head[edge[i].u];

              if(edge[i].u==k)

              dis[edge[i].v]=edge[i].w;

              head[edge[i].u]=i;

              edge1[i].u=edge[i].v;

              edge1[i].v=edge[i].u;

              edge1[i].w=edge[i].w;

              edge1[i].next=head1[edge1[i].u];

              head1[edge1[i].u]=i;

              if(edge1[i].u==k)

              dis1[edge1[i].v]=edge1[i].w;

       }

}

void dijstra()

{

    dis[k]=0;

       visit[k]=1;     

       for(int i=1;i<=n-1;i++)

       {

              int p=0,min1=INF;

              for(int j=1;j<=n;++j)

              {

                     if(!visit[j]&&dis[j]

                     {

                            p=j;

                            min1=dis[j];

                           

                     }

              }

              if(p==0) break;

              visit[p]=1;

              for(int l=head[p];l!=0;l=edge[l].next)

              {

                     if(!visit[edge[l].v]&&edge[l].w+dis[edge[l].u]

                     {

                            dis[edge[l].v]=edge[l].w+dis[edge[l].u];

                     }

              }

       }

}

void dijstra1()

{

    dis1[k]=0;

       visit1[k]=1;   

       for(int i=1;i<=n-1;i++)

       {

              int p=0,min1=INF;

              for(int j=1;j<=n;++j)

              {

                     if(!visit1[j]&&dis1[j]

                     {

                            p=j;

                            min1=dis1[j];

                           

                     }

              }

              if(p==0) break;

              visit1[p]=1;

              for(int l=head1[p];l!=0;l=edge1[l].next)

              {

                     if(!visit1[edge1[l].v]&&edge1[l].w+dis1[edge1[l].u]

                     {

                            dis1[edge1[l].v]=edge1[l].w+dis1[edge1[l].u];

                     }

              }

       }

}

int main()

{

       input();

       dijstra();

       dijstra1();

       for(int i=1;i<=n;++i)

       dis2[i]=dis[i]+dis1[i];

       sort(dis2+1,dis2+n+1);

       printf("%d",dis2[n]);

       return 0;

}


原文地址:https://www.cnblogs.com/csgc0131123/p/5290320.html