1. 程式人生 > >杭電-1599 find the mincost route(最小環有向圖)

杭電-1599 find the mincost route(最小環有向圖)

find the mincost route

Time Limit: 1000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4164    Accepted Submission(s): 1673 Problem Description 杭州有N個景區,景區之間有一些雙向的路來連線,現在8600想找一條旅遊路線,這個路線從A點出發並且最後回到A點,假設經過的路線為V1,V2,....VK,V1,那麼必須滿足K>2,就是說至除了出發點以外至少要經過2個其他不同的景區,而且不能重複經過同一個景區。現在8600需要你幫他找一條這樣的路線,並且花費越少越好。
Input
第一行是2個整數N和M(N <= 100, M <= 1000),代表景區的個數和道路的條數。
接下來的M行裡,每行包括3個整數a,b,c.代表a和b之間有一條通路,並且需要花費c元(c <= 100)。 Output 對於每個測試例項,如果能找到這樣一條路線的話,輸出花費的最小值。如果找不到的話,輸出"It's impossible.". Sample Input 3 3 1 2 1 2 3 1 1 3 1 3 3 1 2 1 1 2 3 2 3 1 Sample Output 3 It's impossible. Author 8600 Source 這道題雖然是有方向的,但是題上說明至少要經過兩個景點,所以說和無向圖是一樣的; 如果沒說至少經過兩個景區,那兩個點就可以組成一個環,此時i可以等於j;
#include <cstdio>  
#include <algorithm>  
#define INF 0x3f3f3f   
using namespace std;  
int map[1100][1100], dist[1100][1100];  
int n, m; 
int ans; 
void Floyd()  
{  
    int k, i, j;  
    ans = INF;  
    for(k = 1; k <= n; k++)//列舉所有最大點   
    {  
        for(i = 1; i < k; i++)//三點成環   
        {  
            for(j = i+1; j < k; j++)//至少經過2個景區 即k,i,j兩兩不等   
            ans = min(ans, map[i][k]+map[k][j]+dist[j][i]);//環長度 為 i->k->j->i 當前dist[i][j]表示的是不經過k的最短路徑   
        }  
        for(i = 1; i <= n; i++)  
        {  
            for(j = 1; j <= n; j++)  
            dist[i][j] = min(dist[i][j], dist[i][k]+dist[k][j]);//更新最短距離   
        }  
    }                                                                                                                                          
    
}  
int main()  
{  
    while(scanf("%d%d", &n, &m) != EOF)  
    {  
        for(int i = 1; i <= n; i++)  
        {  
           for(int j = 1; j <= n; j++)  
           {  
               if(i == j)  
                 map[i][j] = dist[i][j] = 0;  
               else  
                 map[i][j] = dist[i][j] = INF;  
            }  
        }  
        int x, y, d;  
        int i, j;  
        for(i = 0; i < m; i++)  
        {  
             scanf("%d%d%d", &x, &y, &d);  
             if(map[x][y] > d)  
                map[x][y] = map[y][x] = dist[x][y] = dist[y][x] = d;  
         }  
        Floyd(); 
		if(ans == INF)  
          printf("It's impossible.\n");  
        else  
          printf("%d\n", ans);  
    }  
    return 0;  
}