zoukankan      html  css  js  c++  java
  • poj1062(昂贵的聘礼)

    题目大意:

        中文题目不用翻译。

        说下通俗的题意:M代表等级的权限限制,N代表有N个地方,其中酋长地方的编号永远是第一个编号,所以输入的第一组数据就是酋长的允诺编号为1. 接着有X行能与此地方交换物品和拥有替代品之后的价格。其中P代表这个地方的价值,L代表这个地方的等级。问你怎么用自己的聪明才智使得到达编号1 这个地方的花费最少。

    测试实例的走法: 4->2->1  一共花费5250.

    解题思路:

        建图,dijstra最短路。看懂数据建图即可,从1->n,然后可以可以把年轻的探险家从0开始走到“1”这个地方花费的最小价格。  这个用dijstra 注意的一点就是记得等级限制,控制好等级限制即可。

       注意:1.“另外他要告诉你的是,在这个部落里,等级观念十分森严。地位差距超过一定限制的两个人之间不会进行任何形式的直接接触,包括交易。 ”  这句话我觉得本身说的就不太对,刚开始我一直认为 是:节点->节点的差距限制不超过等级 就Ok了,可是这句话的意思是年轻的探险家走过的最短路径,最小的等级和最大的等级限制这个差距不超过M。  这时就需要把所有数据L[1]-M到L[1]+M。这个所有的差距为M的等级枚举一遍。因为假如你不枚举,所产生的路径的等级可能在L[1]-m到L[1]之间,也可能在L[1]到L[1]+m之间得到最小的路径,也可能在别的区间,所以需要枚举所有区间为M 的等级(但在这个区间里必须包括L[1]这个节点的等级)。

        2.“但是如果他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易,他们认为这样等于是间接接触,反过来也一样。”  这句话一点用也没有。  本身以为:假如等级的路径:4-3-4.  这时候等级的限制距离为2时,这种路径是可以的。并不是它说的从等级四到等级三,再之后不能从等级三到等级四。

       3.最后一点注意:这个图是有向图,WA了那么多,discuss数据全过了,这是看自己建图有没有建成了无向图。  这个点也是我在discuss看到的,我是有多菜。

    写了这么多注意,可能是我自己的读题有问题吧。 大家不要在意。

    我的代码还是很简单的,就是弄清楚为啥需要枚举区间即可,然后典型dijstra最短路算出每次枚举的需要的花费,最后枚举过后输出最少的花费。

    代码:

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <sstream>
      4 #include <cstdlib>
      5 #include <cstring>
      6 #include <cstdio>
      7 #include <string>
      8 #include <bitset>
      9 #include <vector>
     10 #include <queue>
     11 #include <stack>
     12 #include <cmath>
     13 #include <list>
     14 //#include <map>
     15 #include <set>
     16 using namespace std;
     17 /***************************************/
     18 #define ll long long
     19 #define int64 __int64
     20 /***************************************/
     21 const int INF = 0x7f7f7f7f;
     22 const double eps = 1e-8;
     23 const double PIE=acos(-1.0);
     24 const int d1x[]= {0,-1,0,1};
     25 const int d1y[]= {-1,0,1,0};
     26 const int d2x[]= {0,-1,0,1};
     27 const int d2y[]= {1,0,-1,0};
     28 const int fx[]= {-1,-1,-1,0,0,1,1,1};
     29 const int fy[]= {-1,0,1,-1,1,-1,0,1};
     30 /***************************************/
     31 void openfile()
     32 {
     33     freopen("data.in","rb",stdin);
     34     freopen("data.out","wb",stdout);
     35 }
     36 /**********************华丽丽的分割线,以上为模板部分*****************/
     37 int lowcost[100],level[100];   //到此地方的最少花费、此地方的等级
     38 int vis[100];   
     39 int map[100][100];
     40 int min1;
     41 void dijstra(int m,int n)
     42 {
     43     int i,j,k;
     44     int min;
     45     min1=INF;
     46     for(int lev=level[1]-m; lev<=level[1]; lev++) //枚举等级区间
     47     {
     48         for(i=1; i<=n; i++)
     49         {
     50             lowcost[i]=map[0][i];
     51             vis[i]=0;
     52         }
     53         int sum=0;
     54         for (j=1; j<=n; j++)
     55             if (level[j]<lev||level[j]>lev+m)   //把不再此等级范围内的地方标记
     56             {
     57                 vis[j]=1;
     58                 sum++;
     59             }
     60         for(i=1; i<=n-1-sum; i++)
     61         {
     62             j=0;
     63             min=INF;
     64             for(k=1; k<=n; k++)
     65             {
     66                 if (!vis[k]&&lowcost[k]<min)
     67                 {
     68                     min=lowcost[k];
     69                     j=k;
     70                 }
     71             }
     72             vis[j]=1;
     73             for(k=1; k<=n; k++)
     74                 if (!vis[k]&&(map[j][k]+lowcost[j]<lowcost[k]))
     75                     lowcost[k]=map[j][k]+lowcost[j];
     76         }
     77         if (lowcost[1]<min1)
     78             min1=lowcost[1];
     79     }
     80 }
     81 int main()
     82 {
     83     int m,n;
     84     while(scanf("%d%d",&m,&n)!=EOF)
     85     {
     86         int i,j;
     87         for(i=0; i<=n; i++)
     88             for(j=0; j<=n; j++)
     89                 map[i][j]=INF;
     90         for(i=1; i<=n; i++)
     91         {
     92             int a,b,c;
     93             scanf("%d%d%d",&a,&b,&c);
     94             level[i]=b;
     95             map[0][i]=a;
     96             for(j=0; j<c; j++)
     97             {
     98                 int x,val;
     99                 scanf("%d%d",&x,&val);
    100                 if (map[i][x]>val)  //有向图
    101                 {
    102                 //    map[i][x]=val;
    103                     map[x][i]=val;
    104                 }
    105             }
    106         }
    107         dijstra(m,n);
    108         printf("%d
    ",min1);
    109     }
    110     return 0;
    111 }
    View Code
    屌丝终有逆袭日,*******。
  • 相关阅读:
    bootstap 折叠
    AtCoder AGC019E Shuffle and Swap (DP、FFT、多项式求逆、多项式快速幂)
    Codeforces Gym 101630J Journey from Petersburg to Moscow (最短路)
    BZOJ 4042 Luogu P4757 [CERC2014]Parades (树形DP、状压DP)
    BZOJ 2734 [HNOI2012]集合选数 (状压DP、时间复杂度分析)
    BZOJ 2759 一个动态树好题 (LCT)
    Codeforces 1205C Palindromic Paths (交互题、DP)
    getopt实现传参自动识别
    powershell笔记
    bat语法需要注意的地方
  • 原文地址:https://www.cnblogs.com/ZhaoPengkinghold/p/3778726.html
Copyright © 2011-2022 走看看