POJ 1062 最短路 昂贵的聘礼
题目连接:http://poj.org/problem?id=1062
思路:这道题一开始我以为是DFS,但是看到是最少金额,我估计觉着应该可能就是最短路。见图的话就是根据题意,看a和b是否有直接关系,通过b,a的优惠价为多少(c),map[a][b] = c但是一般的最短路是明确起点和终点。但是我们的结果就是最小值点。所以我们可以以每个非1点为终点,以1为起点,依次循环找到他们对应的值,取各个路径最小的值,(每个路径的值加上他们本身的价值就是每个路径的值,不要忘记和1的直接价值比较)。然后就是对于等级限制的问题。一开始我吧最高的等级为1的等级+限制级数这样的方法去看是否合法。但是wa。后来把最短路的算法加了一个等级限制的枚举(因为刚才哪种方法最高级-最低等级会变成2*限制等级数)。根据这个物品是否能够购买把他的vis数组化为1就相当于在图中删除了这个节点。
表示一开始照着模板打的时候打错了= =。。。一直WA= =。。。
代码:
View Code
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #define max 0x5fffffff 5 using namespace std; 6 int map[205][205]; 7 struct node 8 { 9 int val; 10 int lev; 11 int n; 12 }a[205];//主要用来存放物品的等级 13 void inint(int n) 14 { 15 int i,j; 16 for(i = 1;i <= n;i++) 17 { 18 for(j = 1;j <= n;j++) 19 map[i][j] = max; 20 map[i][i] = 0; 21 } 22 return; 23 } 24 int is_leagle(int i,int minl,int maxl) 25 { 26 if(a[i].lev > maxl|| minl > a[i].lev) 27 return 0; 28 29 return 1; 30 } 31 int dijks(int n,int s,int m) 32 { 33 int vis[205] = {0},val[205]; 34 int k,i,min,j,pre,maxl,minl; 35 36 37 38 int ans = a[1].val; 39 for(k = 0;k <= m;k++) 40 { 41 memset(vis,0,sizeof(vis)); 42 for(i = 1;i <= n;i++) 43 val[i] = map[s][i];//val存放的就是从1到i的值 44 pre = s; 45 vis[pre] = 1; 46 maxl = a[1].lev+m-k; 47 minl = a[1].lev-k; 48 for(i = 1;i <= n;i++) 49 { 50 if(!is_leagle(i,minl,maxl))//去除不能用的点 51 vis[i] = 1; 52 } 53 min = max; 54 55 for(i = 1;i < n;i++) 56 { 57 min = max; 58 for(j = 1;j <= n;j++) 59 { 60 if(!vis[j] && val[j] > map[pre][j]+val[pre] && map[pre][j] <max ) 61 val[j] = val[pre]+map[pre][j]; 62 } 63 64 for(j = 1;j <= n;j++) 65 { 66 67 if(min > val[j] && !vis[j]) 68 min = val[j],pre = j; 69 } 70 71 vis[pre] = 1; 72 } 73 74 75 int minval; 76 minval = a[1].val;//初始化为a[i]。val 77 for(i = 1;i <= n;i++) 78 { 79 if(val[i]+a[i].val < minval && is_leagle(i,minl,maxl))//寻找这个等级范围的最小值 80 minval = val[i]+a[i].val; 81 } 82 if(ans > minval)//看看ans是否会更改 83 ans = minval; 84 } 85 86 return ans; 87 } 88 89 int main() 90 { 91 int m,n,i,j; 92 while(scanf("%d %d",&m,&n)!= EOF) 93 { 94 95 inint(n); 96 for(i = 1;i <= n;i++) 97 { 98 scanf("%d %d %d",&a[i].val,&a[i].lev,&a[i].n); 99 for(j = 0;j < a[i].n;j++) 100 { 101 int num,val; 102 scanf("%d %d",&num,&val); 103 map[i][num] = val;//建图 104 } 105 } 106 107 108 109 110 111 printf("%d\n",dijks(n,1,m)); 112 } 113 return 0; 114 }