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 ",ans); 76 return 0; 77 }