USACO 2008 March Gold cowjog

Calculate the Kth shortest path in a Directed Acyclic Graph(DAG). Although there exists a complicated way to calculate the Kth shortest Path in Arbitrary Graph, we can get the answer using DP by taking advantage of the property of DAG. A DP way is available because the DAG naturally has got an order which we use frequently.

 

We just maintain an array of size K for each node,  representing first K shortest path from source to that node. When we computing a node I, we just consider all the nodes that leads an edge to I. All we need to do is merging the arrays to get the first K items, then we fill them in the array of Node I.

 

Note: there may be multiple edges between two nodes.

 

Here is the code:

  1. #include <iostream>
  2. using namespace std;
  3. const int N = 1001;
  4. int ad[N][N], len[N][N], d[N][110];
  5. int pt[N];
  6. int n, m, kth;
  7. int main()
  8. {
  9.     int i, j, k, t;
  10.     
  11.     freopen("cowjog.in""r", stdin);
  12.     freopen("cowjog.out""w", stdout);
  13.     
  14.     scanf("%d%d%d",&n, &m, &kth);
  15.     for(; m; m--)
  16.     {
  17.         scanf("%d%d%d",&i, &j, &k);
  18.         ad[j][++ad[j][0]] = i;
  19.         len[j][ad[j][0]] = k;
  20.     }
  21.     memset(d, -1, sizeof(d));
  22.     
  23.     d[n][0] = 0;
  24.     for(i = n - 1; i >= 1; i--)
  25.     {
  26.         memset(pt, 0, sizeof(pt));
  27.         
  28.         for(int cnt = 0; cnt < kth; cnt++)
  29.         {
  30.             int tmp = -1, minD = INT_MAX;
  31.             for(j = 1; j <= ad[i][0]; j++)
  32.             {
  33.                 k = ad[i][j], t = len[i][j];
  34.                 if(d[k][pt[j]] != -1 && t + d[k][pt[j]] < minD)
  35.                 {
  36.                     minD = t + d[k][pt[j]];
  37.                     tmp = j;
  38.                 }
  39.             }
  40.             if(minD != INT_MAX)
  41.             {
  42.                 d[i][cnt] = minD;
  43.                 pt[tmp]++;
  44.             }
  45.         }
  46.     }
  47.     for(i = 0; i < kth; i++)
  48.         printf("%d/n",d[1][i]);
  49.     scanf("%d",&n);
  50.     return 0;
  51. }

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值