拓扑最长路

来源:互联网 发布:七天网络怎样查分 编辑:程序博客网 时间:2024/05/16 00:26

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=941


由于n很小,floyd算法写起来方便,先用这个A了一下:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /*0.162s*/  
  2.   
  3. #include<bits/stdc++.h>  
  4. using namespace std;  
  5. const int mx = 105;  
  6.   
  7. int d[mx][mx];  
  8.   
  9. void floyd(int n)  
  10. {  
  11.     int k, i, j;  
  12.     for (k = 1; k <= n; ++k)  
  13.         for (i = 1; i <= n; ++i)  
  14.             for (j = 1; j <= n; ++j)  
  15.                 d[i][j] = min(d[i][j], d[i][k] + d[k][j]);  
  16. }  
  17.   
  18. int main()  
  19. {  
  20.     int cas = 0, n, s, i, a, b, dis, to;  
  21.     while (scanf("%d%d", &n, &s), n)  
  22.     {  
  23.         memset(d, 0x3f, sizeof(d));  
  24.         for (i = 1; i <= n; ++i) d[i][i] = 0;  
  25.         while (scanf("%d%d", &a, &b), a)  
  26.             d[a][b] = -1; ///取负值  
  27.         floyd(n);  
  28.         dis = 0;  
  29.         for (i = 1; i <= n; ++i)  
  30.         {  
  31.             if (d[s][i] < dis)  
  32.             {  
  33.                 dis = d[s][i];  
  34.                 to = i;  
  35.             }  
  36.         }  
  37.         printf("Case %d: The longest path from %d has length %d, finishing at %d.\n\n", ++cas, s, -d[s][to], to);  
  38.     }  
  39.     return 0;  
  40. }  

然后由于是DAG,于是用拓扑排序A了一下,快的不是一点半点:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /*0.038s*/  
  2.   
  3. #include<bits/stdc++.h>  
  4. using namespace std;  
  5. const int mx = 105;  
  6.   
  7. vector<int> G[mx];  
  8. bool vis[mx];  
  9. int topo[mx], disTo[mx], cnt;  
  10.   
  11. void dfs(int i)  
  12. {  
  13.     vis[i] = true;  
  14.     for (int j = 0; j < G[i].size(); ++j) ///对于vector,[0,size())  
  15.         if (!vis[G[i][j]]) dfs(G[i][j]);  
  16.     topo[cnt++] = i;  
  17. }  
  18.   
  19. void dagSP(int s)  
  20. {  
  21.     int i = cnt, j, v;  
  22.     while (topo[--i] != s);  
  23.     memset(disTo, 0x3f, sizeof(disTo)); /// 初始化  
  24.     disTo[s] = 0;  
  25.     for (; i >= 0; --i)  
  26.     {  
  27.         v = topo[i];  
  28.         for (j = 0; j < G[v].size(); ++j) ///注意是以v为主  
  29.             disTo[G[v][j]] = min(disTo[G[v][j]], disTo[v] - 1);  
  30.     }  
  31. }  
  32.   
  33. int main()  
  34. {  
  35.     int cas = 0, n, s, i, a, b, dis, to;  
  36.     while (scanf("%d%d", &n, &s), n)  
  37.     {  
  38.         for (i = 1; i <= n; ++i) G[i].clear();  
  39.         while (scanf("%d%d", &a, &b), a) G[a].push_back(b);  
  40.         cnt = 0; /// 最重要的初始化!  
  41.         memset(vis, 0, sizeof(vis));  
  42.         for (i = 1; i <= n; ++i)  
  43.             if (!vis[i]) dfs(i);  
  44.         dagSP(s);  
  45.         dis = 0;  
  46.         for (i = 1; i <= n; ++i)  
  47.         {  
  48.             if (disTo[i] < dis)  
  49.             {  
  50.                 dis = disTo[i];  
  51.                 to = i;  
  52.             }  
  53.         }  
  54.         printf("Case %d: The longest path from %d has length %d, finishing at %d.\n\n", ++cas, s, -disTo[to], to);  
  55.     }  
  56.     return 0;  

0 0
原创粉丝点击