。。。

导航

hdu 2680 Choose the best route【dijstra+反向建图】

http://acm.hdu.edu.cn/showproblem.php?pid=2680

题意:给出顶点数和路径总数及要到达的终点,再给出可以到达终点的多个起点,输出这些起点中到终点的最短路径。

思路:如果找每个起点到终点的距离,最后比较出最小值,会tle(亲测有效),正解思路是反向建图,把题目所给的终点当作起点,多个起点当作终点,用一次dijstra求起点到每个顶点的最短路径,最后遍历查找起点到每个终点的路径的最短路。

看了别人的题解才知道,还有一个地方比较坑,同一路径,取权值最小的边,不过平时自己就习惯了判断自重边,反正也不影响结果,想不到这次避开了这个坑点。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
#define N 1100
int w[N][N],dis[N],book[N],num[N];
int main()
{
     int n,m,s,t1,t2,t3,ans,min1,u,x,i,j;
     while(scanf("%d%d%d",&n,&m,&s)!=EOF)
     {
         for(i = 0; i <= n; i ++)
             for(j = 0; j <= n; j ++)
                     w[i][j] = inf;
        for(i = 1; i <= m; i ++)
        {
            scanf("%d%d%d",&t1,&t2,&t3);
            if(t3 < w[t2][t1])//判断自重边 
                w[t2][t1] = t3;//反向建图 
        }
         scanf("%d",&x);
         for(i = 1; i <= x; i ++)
             scanf("%d",&num[i]);
         memset(book,0,sizeof(book));
         for(i = 1; i <= n; i ++)
             dis[i] = w[s][i];
         book[s] = 1;
         for(i = 1; i < n; i ++)
         {
             min1 = inf;
             for(j = 1; j <= n; j ++)
                 if(!book[j]&&dis[j]<min1)
                 {
                     min1 = dis[j];
                     u = j;
                 }
             book[u] = 1;
             for(j = 1; j <= n; j ++)
                 if(!book[j]&&dis[j] > dis[u]+w[u][j])
                     dis[j] = dis[u]+w[u][j];
         }
         ans = inf;
         for(i = 1; i <= x; i ++)
            ans = min(ans,dis[num[i]]);//取反转图后起点到多个终点的最小权值 
        if(ans == inf)
             printf("-1\n");
         else
             printf("%d\n",ans);
 }
 return 0;
}

 

posted on 2017-09-20 23:15  大学僧  阅读(105)  评论(0编辑  收藏  举报