usaco 4.1 Fence Loops 最小环

 给点各边的连接关系,求最小环,如果给定的是点的关系,可以用floyd简单的求出,但是现在给定的是边的关系,如果转换成点的关系,将会很麻烦,然而最

小环也可以用dijkstra来求,枚举每条边,求出到自己的最短路即为最小环的长度

 

 

  1. #include <iostream>
  2. #include <algorithm>
  3. using namespace std;
  4. /*
  5. PROG: fence6
  6. LANG: C++
  7. ID: heben991
  8. */
  9. const int N = 220, INF = 100000000;
  10. int v, e, w[N], num[N], pos[N],
  11.     l[N][2][N], ans;
  12. int dist[N], pre[N];
  13. bool mark[N];
  14. int dijkstra(int s)
  15. {
  16.     int i, j, k, t, u, v;
  17.     for(i = 1; i <= e; ++i)
  18.     {
  19.         dist[i] = INF;
  20.         mark[i] = 0;
  21.     }
  22.     for(i = 1; i <= l[s][0][0]; ++i)
  23.     {
  24.         t = l[s][0][i];
  25.         dist[t] = w[s];
  26.         pre[t] = s;
  27.     }
  28.     while(1)
  29.     {
  30.         u = 0; t = INF;
  31.         for(i = 1; i <= e; ++i)
  32.         if(!mark[i] && dist[i] < t)
  33.         {
  34.             t = dist[i];
  35.             u = i;
  36.         }
  37.         if(0 == u)break;
  38.         if(s == u) return dist[s];
  39.         mark[u] = 1;
  40.         for(i = 1; i <= l[u][0][0]; ++i)
  41.             if(pre[u] == l[u][0][i]) break;
  42.         if(i <= l[u][0][0]) k = 1;
  43.         else k = 0;
  44.         for(i = 1; i <= l[u][k][0]; ++i)
  45.         {
  46.             v = l[u][k][i];
  47.             if( dist[u] + w[u] < dist[v] )
  48.             {
  49.                 dist[v] = dist[u] + w[u];
  50.                 pre[v] = u;
  51.             }
  52.         }
  53.     }
  54.     return INF;
  55. }
  56. int main()
  57. {
  58.     int i, j, k, t;
  59.     freopen("fence6.in""r", stdin);
  60.     freopen("fence6.out","w",stdout);
  61.     scanf("%d", &e);
  62.     for(i = 1; i <= e; ++i)
  63.     {
  64.         scanf("%d%d%d%d", &num[i], &w[i], l[i][0], l[i][1]);
  65.         for(j = 0; j < 2; ++j)
  66.         {
  67.             for(k = 1; k <= l[i][j][0]; ++k)
  68.             {
  69.                 scanf("%d", &l[i][j][k]);
  70.             }
  71.         }
  72.     }
  73.     for(i = 1; i <= e; ++i)
  74.     {
  75.         pos[num[i]] = i;
  76.     }
  77.     for(i = 1; i <= e; ++i)
  78.         for(j = 0; j < 2; ++j)
  79.             for(k = 1; k <= l[i][j][0]; ++k)
  80.                 l[i][j][k] = pos[ l[i][j][k] ];
  81.     ans = INF;
  82.     for(i = 1; i <= e; ++i)
  83.     {
  84.         ans <?= dijkstra(i);
  85.     }
  86.     printf("%d/n",ans);
  87.     return 0;
  88. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值