POJ 1062 ( dijkstra )

http://poj.org/problem?id=1062

一个中文题,一个多月之前我做过,当时我是用搜索写的,不过苦于卡在无法确定等级关系,所以就错了。

看了别人的博客后,我还是不是很理解所谓的枚举等级是怎样枚举,因为我觉得在递归的时候,我真的不知道怎么枚举等级。

然后今天在看到了一个人写的,枚举等级怎么枚举,我才发现我用那个搜索写的话,我还是有问题。所以我就用这个新学的dijkstra写

所谓的枚举等级,就是以每一个等级都视为最低等级来进行枚举。

比如等级限制1,而那个酋长的等级是3,那么你就应该枚举2-4,和3-5的等级的人。

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 #define inf 9999999
 5 
 6 int m,n;
 7 int price[105],d[105];
 8 int graph[105][105];
 9 int rank[105];
10 bool mark[105],limit[105];
11 
12 int dijkstra()
13 {
14     int result = inf;
15     int k,dis;
16     memset(mark,false,sizeof(mark));
17     d[ 1 ] = 0;           
18     for(int i = 2 ; i <= n ; i++)
19         d[ i ] = inf;
20     for(int i = 1 ; i <= n ; i++)     //dijkstra是这个循环
21     {
22         k = 0;
23         dis = inf;
24         for(int j=1 ; j <= n ;j++)
25             if(!mark[ j ] && d[ j ] <= dis && limit[ j ])
26             {
27                 k = j;
28                 dis = d[ j ];
29             }
30             mark[ k ] = true;
31             for(int j = 1 ; j <= n ; j++)
32             {
33                 if(limit[ j ] && d[ j ] > d[ k ] + graph[ k ][ j ])
34                     d[ j ] = d[ k ] + graph[ k ][ j ];
35             }
36     }
37     for(int i = 1 ;i <= n ;i++)
38     {
39         d[ i ] += price[ i ];    //d[i] 是存储着交换i次后的价钱。
40         if(d[ i ] < result)
41             result = d[ i ];
42     }
43     return result;
44 }
45 
46 int main()
47 {
48     int x,t,v,ans = inf;
49     scanf("%d%d",&m,&n);
50     for(int i = 0 ; i <= n ; i++)      //进行构图。
51         for(int j = 0;j <= n ; j++)
52             if( i == j )
53                 graph[ i ][ j ] = 0;
54             else
55                 graph[ i ][ j ] = inf;
56     for(int i = 1 ; i <= n ; i++)
57     {
58         scanf("%d%d%d",&price[i],&rank[i],&x);
59         for(int j = 0 ; j < x ; j++)
60         {
61             scanf("%d%d",&t,&v);
62             graph[ i ][ t ] = v;
63         }
64     }
65     for(int i = 0 ; i <= m ; i++)      //这里就是枚举等级,把可以和酋长交换的人进行标记,然后进行最短路的寻找。
66     {
67         memset(limit,0,sizeof(limit));
68         for(int j = 1 ; j <= n ; j++)
69             if(rank[ j ] >= rank[ 1 ] - m + i && rank[ j ] <= rank[ 1 ] + i)
70                 limit[ j ] = true;
71             t = dijkstra();
72             if(ans > t)
73                 ans = t;
74     }
75     printf("%d\n",ans);
76     return 0;
77 }

 

posted @ 2016-08-02 15:43  一个_小菜鸟  阅读(195)  评论(0编辑  收藏  举报