zoukankan      html  css  js  c++  java
  • POJ 1062 dijkstra + 枚举

    这题从下午七点做到晚上的九点半,才做出来。

    题意,有一个人A,要去人B那里买东西,人B说了一个价格,然后说如果你能把人C的东西弄来,再加上一部分钱(比直接买人B东西的价格少),也能买到。

    于是人A又去了人C那里,人C说了同上的话。依次类推。

    但是这个交易圈子里有个规定,就是每个人都有一个等级,如果两个人相差k个等级以上,是不能产生直接或者间接交易的。

    问最后你一定要买到人A的东西,最少要多少钱。

    分析,分析过后,可以通过交易关系,A需要B的东西,将一条边由B连上A,建立有向图。如果没有等级制度,就是一个裸的dijkstra。存在等级制度加大了题目难度。一个比较简单的处理方法是,如果人A的等级为k,最后存在一条最短路。

    那么最短路上的人的权值一定在区间 [k-m,k] [k-m+1,k+1] [k-m+2,k+2] ...... [k,k+m] 这些区间中。枚举区间范围,然后每个范围进行dijkstra,纪录最小答案。

    注意细节问题就好。

    这题数据很小啊,于是就没有套优先队列优化。

     1 /* When all else is lost the future still remains. */
     2 /* You can be the greatest */
     3 #define rep(X,Y,Z) for(int X=(Y);X<(Z);X++)
     4 #define drep(X,Y,Z) for(int X=(Y);X>=(Z);X--)
     5 #define fi first
     6 #define se second
     7 #define mk(X,Y) make_pair((X),(Y))
     8 #define inf 0x3f3f3f3f
     9 #define clr(X,Y) memset(X,Y,sizeof(X))
    10 #define pb push_back
    11 //head
    12 #include <iostream>
    13 #include <stdio.h>
    14 #include <queue>
    15 #include <algorithm>
    16 #include <string>
    17 #include <map>
    18 #include <string.h>
    19 using namespace std;
    20 #define maxN 110
    21 vector<pair<int,int> > cur[maxN];
    22 int val[maxN];
    23 int lev[maxN];
    24 int dis[maxN];
    25 bool mark[maxN];
    26 void init(int n){
    27     rep(i,0,n+1) cur[i].clear();
    28     clr(mark,0);
    29     return ;
    30 }
    31 int find(int n){
    32     int ans = -1;
    33     int min_val = 2 * inf;
    34     rep(i,1,n+1){
    35         if(mark[i]) continue;
    36         if(dis[i] < min_val){
    37             min_val = dis[i];
    38             ans = i;
    39         }
    40     }
    41     return ans ;
    42 }
    43 int dij(int n , int m){
    44     int ans = val[1];
    45     rep(low,lev[1]-m,lev[1]+1){
    46         int p;
    47         int high = low + m;
    48         rep(i,1,n+1) dis[i] = val[i];
    49         clr(mark,0);
    50         //
    51         while((p = find(n)) != -1){
    52             if(mark[1]) break;
    53             //printf("%d 
    ",p);
    54             //check(n);
    55             mark[p] = 1;
    56             if(lev[p] > high || lev[p] < low) continue;
    57             int size = cur[p].size();
    58             rep(i,0,size){
    59                 int aim = cur[p][i].fi;
    60                 int w = cur[p][i].se;
    61                 if(lev[aim] < low || lev[aim] > high) continue;
    62                 dis[aim] = min(dis[aim],dis[p] + w);
    63             }
    64         }
    65         ans = min(ans,dis[1]);
    66     }
    67     return ans;
    68 }
    69 int main(){
    70     int m , n;
    71     while(~scanf("%d %d",&m,&n)){
    72         init(n);
    73         rep(i,1,n+1){
    74             int w , l , num;
    75             scanf("%d %d %d",&w,&l,&num);
    76             val[i] = w; lev[i] = l;
    77             rep(j,0,num){
    78                 int a , b;
    79                 scanf("%d %d",&a,&b);
    80                 cur[a].pb(mk(i,b));
    81             }
    82         }
    83         printf("%d
    ",dij(n,m));
    84     }
    85     return 0;
    86 
    87 }
  • 相关阅读:
    easyui 后台系统引入富文本编辑器的使用
    easyui datagrid 表格动态隐藏部分列的展示
    java ArrayList源码分析(转载)
    propertychange方法
    CSS margin-top 属性
    easyui-textbox input输入框的一种取值方式
    jquery next()方法
    jquery children()方法
    一段简单的表格样式
    常用的排序算法的时间复杂度和空间复杂度
  • 原文地址:https://www.cnblogs.com/ticsmtc/p/5958406.html
Copyright © 2011-2022 走看看