Coder Space

PKU 1062 昂贵的聘礼 --- 两点间最短路径+等级限制

Dijkstra算法
每个物品对应于一结点,具有代替关系的物品用边相连,边权为优惠价格,建图。增加一个结点N+1,连接每个结点,权值等于结点对应物品的价格,表示直接支付。题目即转化为求N+1结点的到结点1(酋长许诺)的最短路。Dijkstra算法求解。
关于等级限制:(酋长等级未必最高)
设酋长等级为lv[1],枚举每次可行结点(lv[1]-M)~lv[1]....lv[1]~(lv[1]+M),不在范围内的结点,设置flag为false,经过M次Dijkstra过程求得最小值,即为解。


  1 #include<iostream>
  2 #include<limits>
  3 
  4 using namespace std;
  5 
  6 const int maxN = 105;
  7 const int INF = numeric_limits<int>::max();
  8 
  9 int s[maxN][maxN];
 10 int lv[maxN];
 11 
 12 int dist[maxN];
 13 bool flag[maxN];
 14 
 15 //寻找最短路径
 16 int Dijkstra(int n, int v) {
 17 
 18     for (int i = 1; i <= n; i++) {
 19         dist[i] = s[v][i];
 20     }
 21 
 22     dist[v] = 0;
 23     flag[v] = true;
 24 
 25     for (int i = 1; i < n; i++) {
 26         int temp = INF;
 27         int u = v;
 28         for (int j = 1; j <= n; j++) {
 29             if ((!flag[j] && dist[j] < temp)) {
 30                 u = j;
 31                 temp = dist[j];
 32             }
 33         }
 34 
 35         if (u == 1) {
 36             return dist[u];
 37         }
 38 
 39         flag[u] = true;
 40 
 41         for (int j = 1; j <= n; j++) {
 42             if ((!flag[j] && s[u][j] != INF)) {
 43                 int newDist = dist[u] + s[u][j];
 44                 if (newDist < dist[j]) {
 45                     dist[j] = newDist;
 46                 }
 47             }
 48         }
 49     }
 50     return -1;
 51 }
 52 
 53 //把不符合等级要求的物品设置为不能访问
 54 void MakeFlag(int n, int f, int t) {
 55 
 56     for (int i = 1; i <= n; i++) {
 57         if (lv[i] >= f && lv[i] <= t) {
 58             flag[i] = false;
 59         } else {
 60             flag[i] = true;
 61         }
 62     }
 63 
 64 }
 65 
 66 int main() {
 67 
 68     int M, N;
 69     int X,T,V;
 70     int res, tmp;
 71 
 72     int i, j;
 73 
 74     while (cin >> M >> N) {
 75 
 76         //初始化
 77         for (i = 1; i <= N; i++) {
 78             for (j = 1; j <= N; j++) {
 79                 s[i][j] = INF;
 80             }
 81         }
 82         //输入数据
 83         for (i = 1; i <= N; i++) {
 84 
 85             cin >> s[N + 1][i] >> lv[i] >> X;
 86 
 87             for (j = 0; j < X; j++) {
 88 
 89                 cin >> T >> V;
 90                 s[T][i] = V;
 91             }
 92         }
 93 
 94         res = INF;
 95         for (int t = M; t >= 0; t--) {
 96             MakeFlag(N + 1, lv[1- t, lv[1+ M - t);
 97             tmp = Dijkstra(N + 1, N + 1);
 98             if(tmp < res){
 99                 res=tmp;
100             }
101         }
102         cout<<res<<endl;
103     }
104 }

posted on 2010-05-07 17:03 David Liu 阅读(194) 评论(0)  编辑 收藏 引用 所属分类: 图论


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


My Links

Blog Stats

常用链接

留言簿

文章分类

文章档案

搜索

最新评论