poj 1062昂贵的聘礼 dijkstra bellman dfs都可以

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

本题难点在于构图,比较巧的做法是将探险家作为另一个节点(第n+1个节点)并将该节点定为源点,之后把其余节点 i (人)直接买他的东西所花费的价钱作为第n+1个节点到第i个节点的权值,方向是由n+1指向i;其他的边权值由替代品x的价格来构造,方向是由代替品x指向索要者y。可以发现构造的有向带权图,由源点n+1指向各个节点。我们的任务转化为求n+1节点到第一个节点(酋长)的最短路径。用dijkstra或bellman都可以做。dfs暂时没看。

注意一个点本题限制了等级,则在酋长允许的等级区间 【level[1]-m,level[1]+m】中枚举每一个等级,每次都运用一次最短路,之后取最小值。

 

 1 //huJJ 1062 Accepted 468K 0MS G++ 956B 
2
3 #include<stdio.h>
4 #define INF 1000000
5 #define MAX 200
6 int mat[MAX][MAX],m,n;
7 int v[MAX],dis[MAX],level[MAX];
8 void print()
9 {
10 for(int i=1;i<=n+1;i++)
11 printf("%d ",dis[i]);
12 printf("\n");
13 }
14 void dijkstra(int deg)
15 {
16 for(int i=1;i<=n;i++)
17 v[i]=0,dis[i]=INF;
18 dis[n+1]=0,v[n+1]=0;
19 for(int j=1;j<=n+1;j++)
20 {
21 int k=-1;
22 for(int i=1;i<=n+1;i++)
23 {
24 if(level[i]<deg||level[i]>deg+m) v[i]=1;
25 if(!v[i]&&(k==-1||dis[i]<dis[k]))
26 k=i;
27 }
28 //printf("k=%d\n",k);
29 if(k==-1||k==1) return;
30 v[k]=1;
31 for(int i=1;i<=n+1;i++)
32 {
33 if(!v[i]&&dis[i]>dis[k]+mat[k][i])
34 dis[i]=dis[k]+mat[k][i];
35 }
36 //print();
37 }
38 }
39
40 int main()
41 {
42 int p,to,c;
43 scanf("%d%d",&m,&n);
44 for(int i=1;i<=n;i++)
45 for(int j=1;j<=n;j++)
46 mat[i][j]=INF;
47 for(int k=1;k<=n;k++)
48 {
49 scanf("%d%d%d",&mat[n+1][k],&level[k],&c);
50 for(int i=0;i<c;++i)
51 scanf("%d%d",&to,&p),mat[to][k]=p;
52 }
53 level[n+1]=level[1];
54 int i=0,res=INF;
55 for(i=level[1]-m;i<=level[1]+m;i++)
56 {
57 dijkstra(i);
58 if(dis[1]<res) res=dis[1];
59 }
60 printf("%d\n",res);
61
62 }

 

posted @ 2012-02-10 00:26  HUJJ  阅读(237)  评论(0编辑  收藏  举报