HDU

 题目:对于一个有向图给出多起点和一个终点 问哪个起点到终点路径最短

1, directed ways 有向边

2,点有1000个 ,用floyd的话会超时

3,虽然是多起点,但只有一个终点,所以还是单一源点问题,用djikstra,终点看做原点

4,因为从终点寻起点,所以建图时要把所有的路反过来建

  

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#define ll long long
#define MAXN 1000000+50
#define mst( x,a ) memset ( x ,a,sizeof ( x ) )
using namespace std;

const int inf = 0x3f3f3f3f ;

struct edge{
     int to;
     int w;
};

int  ans_d[1005] ,vis[1005] ;

int main ( ){
     int n,m,en,st,t;
     while( ~scanf( "%d%d%d" ,&n ,&m ,&en)){
            mst( ans_d,inf );
            mst ( vis,0 );
            vector <edge> e[1005];
         for( int i=0 ; i<m ; i++){
             int a, b ,c;
            scanf( "%d%d%d", &a ,&b ,&c );
             edge e1;
             e1.w=c;
             e1.to=a;  e[b].push_back( e1 );    //反向建图
             //e1.to=b;  e[a].push_back( e1 );
         }
        //dijkstra
         ans_d [en] =0;
         int flag=1;
         while ( true ){
             flag= 1;
             int mn=inf , mni;
             for( int j=1 ; j<=n ;j++){
                if ( !vis[j] && mn>ans_d[j]){
                    mn= ans_d[j];
                    mni=j;
                    flag=0;
                }
             }
             if(flag) break;
             vis[mni]=1;
             int es=e[mni].size( );
             for( int j=0 ; j<es ; j++){
                 int to=e[mni][j].to;
                 int w=e[mni][j].w;
                 ans_d [to]= min ( ans_d[to] , ans_d[mni]+w );
             }
         }
         int ans=inf;
         scanf("%d",&t);
         while( t-- ){
             scanf("%d" ,&st);
             ans = min( ans , ans_d[st] );
         }
         if(ans == inf)printf("-1
");
         else printf("%d
",ans );
     }

     return 0;
}
原文地址:https://www.cnblogs.com/-ifrush/p/10577635.html