Hdu-2680 Choose the best route

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2680

题目大意:

给你一个有向图,一个起点集合,一个终点,求最短路。。。。

解题思路:

1.自己多加一个超级源点,把起点集合连接到超级源点上,然后将起点与超级源点的集合的路径长度设为0,这样就称为一个n+1个点的单源最短路算法。。。。。

2.反向图+终点的Dijkstra,然后记录最小值。

思路1的代码如下:

[cpp]  view plain copy
  1. #include  
  2. #include  
  3. #include  
  4. using namespace std;  
  5.   
  6. #define MAX 0x3f3f3f3f  
  7. #define N 1010  
  8.   
  9. int num, road, destination;  
  10. int map[N][N], dis[N];  
  11. bool visit[N];  
  12.   
  13. void Dijkstra()  
  14. {  
  15.     int temp, k;  
  16.     memset(visit, 0, sizeof(visit));  
  17.     for(int i = 0; i <= num; ++i) //n+1个点的Dijkstra  
  18.         dis[i] = map[0][i];  
  19.     dis[0] = 0;  
  20.     visit[0] = 1;  
  21.     for(int i = 0; i <= num; ++i)  
  22.     {  
  23.         temp = MAX;  
  24.         for(int j = 0; j <= num; ++j)  
  25.             if(!visit[j] && temp > dis[j])  
  26.                 temp = dis[k = j];  
  27.         if(temp == MAX) break;  
  28.         visit[k] = 1;  
  29.         for(int j = 0; j <= num; ++j)  
  30.             if(!visit[j] && dis[j] > dis[k] + map[k][j])  
  31.                 dis[j] = dis[k] + map[k][j];  
  32.     }  
  33. }  
  34.   
  35. int main()  
  36. {  
  37.     int x, y, cost, exp, cost1;  
  38.     while(scanf("%d%d%d", &num, &road, &destination) != EOF)  
  39.     {  
  40.         memset(map, MAX, sizeof(map));  
  41.         for(int i = 1; i <= road; ++i)  
  42.         {  
  43.             scanf("%d%d%d", &x, &y, &cost);  
  44.             if(cost < map[x][y])  
  45.             map[x][y] = cost;  
  46.         }  
  47.         scanf("%d", &exp);  
  48.         for(int i = 1; i <= exp; ++i) //巧妙之处,加超级源点  
  49.         {  
  50.             scanf("%d", &cost1);  
  51.             map[0][cost1] = 0;  
  52.         }  
  53.         Dijkstra();  
  54.         if(dis[destination] == MAX) printf("-1\n");  
  55.         else printf("%d\n", dis[destination]);  
  56.     }  
  57.     return 0;  
  58. }  
思路2代码如下:

[cpp]  view plain copy
  1. #include  
  2. #include  
  3. #include  
  4. using namespace std;  
  5.   
  6. #define MAX 0x3f3f3f3f  
  7. #define N 1010  
  8.   
  9. int num, road, destination;  
  10. int map[N][N], dis[N], oppo[N];  
  11. bool visit[N];  
  12.   
  13. void Dijkstra(int start)  
  14. {  
  15.     int temp, k;  
  16.     memset(visit, 0, sizeof(visit));  
  17.     for(int i = 1; i <= num; ++i)   
  18.         dis[i] = map[start][i];  
  19.     dis[start] = 0;  
  20.     visit[start] = 1;  
  21.     for(int i = 1; i <= num; ++i)  
  22.     {  
  23.         temp = MAX;  
  24.         for(int j = 1; j <= num; ++j)  
  25.             if(!visit[j] && temp > dis[j])  
  26.                 temp = dis[k = j];  
  27.         if(temp == MAX) break;  
  28.         visit[k] = 1;  
  29.         for(int j = 1; j <= num; ++j)  
  30.             if(!visit[j] && dis[j] > dis[k] + map[k][j])  
  31.                 dis[j] = dis[k] + map[k][j];  
  32.     }  
  33. }  
  34.   
  35. int main()  
  36. {  
  37.     int x, y, cost, exp, minn;  
  38.     while(scanf("%d%d%d", &num, &road, &destination) != EOF)  
  39.     {  
  40.         memset(map, MAX, sizeof(map));  
  41.         for(int i = 1; i <= road; ++i)  
  42.         {  
  43.             scanf("%d%d%d", &x, &y, &cost);  
  44.             if(cost < map[y][x]) //巧妙之处:反向图  
  45.             map[y][x] = cost;  
  46.         }  
  47.         scanf("%d", &exp);  
  48.         for(int i = 1; i <= exp; ++i)  
  49.             scanf("%d", &oppo[i]);  
  50.         Dijkstra(destination);  
  51.         minn = MAX;  
  52.         for(int i = 1; i <= exp; ++i) //起点找到终点最小值  
  53.             if(dis[oppo[i]] < minn)  
  54.                 minn = dis[oppo[i]];  
  55.         if(minn == MAX) printf("-1\n");  
  56.         else printf("%d\n", minn);  
  57.     }  
  58.     return 0;  
  59. }  

你可能感兴趣的:(图论)