任意の2点間の最短問題Floyd-Warshallアルゴリズム

11310 ワード

このアルゴリズムは前のBellman-F=Fordアルゴリズムと同じで、負のループを判断できます.
dp[i][j]が負の頂点iであることを確認するだけで良いです.
 
 1 //               
 2 // Floyed-Warshall  
 3 //    O(N^3),N    
 4 
 5 #include 
 6 #include 
 7 
 8 using namespace std;
 9 //  dp      
10 // dp[k][i][j]: i j,    K       
11 // dp[k][i][j]=dp[k-1][i][k] + dp[k-1][k][j]
12 //         ,      ,      
13 //          , k,      ,                k k    
14 //        ,k k   ,    ,          (    d[i][j]<0,    )
15 //16 //   dp          
17 
18 const int max_N = 200+2;
19 const int max_E = 10000+2;
20 const int INF = 1e9;
21 
22 int dp[max_N][max_N];
23 int N,E;
24 
25 void floyd_warshall()
26 {
27     for(int k=0;kk)
28     {
29         for(int i=0;ii)
30         {
31             for(int j=0;jj)
32             {
33                 dp[i][j]=min( dp[i][j],dp[i][k]+dp[k][j] );
34             }
35         }
36     }
37 }
38 
39 int main()
40 {
41     scanf("%d %d",&N,&E);
42     int a,b,c;
43     for(int i=0;ii)
44     {
45         for(int j=0;jj)
46         {
47             if(i==j)
48             {
49                 dp[i][j]=0;
50             }
51             else
52             {
53                 dp[i][j]=INF;
54             }
55         }
56     }
57     for(int i=0;ii)
58     {
59         scanf("%d %d %d",&a,&b,&c);
60         dp[a][b]=c;
61         //    
62         dp[b][a]=c;
63     }
64     floyd_warshall();
65 
66     for(int i=0;ii)
67     {
68         for(int j=0;jj)
69         {
70             printf("%d ",dp[i][j]);
71         }
72         printf("
"); 73 } 74 return 0; 75 } 76 /* 77 7 10 78 0 1 2 79 0 2 5 80 1 2 4 81 1 3 6 82 1 4 10 83 2 3 2 84 3 5 1 85 4 5 3 86 4 6 5 87 5 6 9 88 89 90 91 92 0 2 5 7 11 8 16 93 2 0 4 6 10 7 15 94 5 4 0 2 6 3 11 95 7 6 2 0 4 1 9 96 11 10 6 4 0 3 5 97 8 7 3 1 3 0 8 98 16 15 11 9 5 8 0 99 */