zoukankan      html  css  js  c++  java
  • 1062:昂贵的聘礼(最短路/枚举)

    题面链接

    题解

    1 //最短路径——Dijkstra算法  

    2 //此题的关键在于等级限制的处理,最好的办法是采用枚举,即假设酋长等级为5,等级限制为2,那么需要枚举等级从3~5,4~6,5~7  

    3 //从满足改等级范围的结点组成的子图中用Dijkstra来算出最短路径  

    4 //小结,通过枚举的方式可以消除一些图与图之间的限制 

    C++代码

    #include <set>
    #include <map>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define  pi acos(-1.0)
    #define  eps 1e-9
    #define  fi first
    #define  se second
    #define  rtl   rt<<1
    #define  rtr   rt<<1|1
    #define  bug         printf("******
    ")
    #define  mem(a,b)    memset(a,b,sizeof(a))
    #define  name2str(x) #x
    #define  fuck(x)     cout<<#x" = "<<x<<endl
    #define  f(a)        a*a
    #define  sf(n)       scanf("%d", &n)
    #define  sff(a,b)    scanf("%d %d", &a, &b)
    #define  sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
    #define  sffff(a,b,c,d) scanf("%d %d %d %d", &a, &b, &c, &d)
    #define  pf          printf
    #define  FRE(i,a,b)  for(i = a; i <= b; i++)
    #define  FREE(i,a,b) for(i = a; i >= b; i--)
    #define  FRL(i,a,b)  for(i = a; i < b; i++)+
    #define  FRint(i,a,b) for(i = a; i > b; i--)
    #define  FIN         freopen("data.txt","r",stdin)
    #define  gcd(a,b)    __gcd(a,b)
    #define  lowbit(x)   x&-x
    using namespace std;
    typedef long long  LL;
    typedef unsigned long long ULL;
    const int maxn = 205;
    const int INF = 0x3f3f3f3f;
    int n,mp[maxn][maxn], k[maxn], dis[maxn];
    bool cha[maxn];
    bool vis[maxn];
    int l[maxn],v[maxn];
    int p[maxn];
    int minn;
    int dijkstra()
    {
        int minn = INF;
        memset(vis,false,sizeof(vis)); //清除所有点的标号 
        for(int i=1;i<=n;i++)
            dis[i] = INF; //设d[1] = 0,其它为 INF 
        dis[1] = 0; //(此处还未加上进入改点的花费)自己换自己为0 
        
        for(int i=1;i<=n;i++) //循环n 次 
        {
            int x, m = INF;
            for(int y=1;y<=n;y++)
            { //在所有未标号且满足等级限制的点中选出 d值最小的点 x 
                if(!vis[y] && dis[y] <= m && cha[y])
                    m = dis[x=y];
            }
            vis[x] = true; //标记点x 
            
            for(int y=1;y<=n;y++) // 对于从x出发的所有边 (x, y)更新dist 
            {
                if(cha[y]) //若满足等级限制
                    dis[y] = min(dis[y], dis[x]+mp[x][y]);
            }
        }
        
        for(int y=1;y<=n;y++)
        { //对于每个dist[y]还要满足进入改点的花费 
            dis[y] += p[y];
            minn = min(minn,dis[y]);
        }
        
        return minn; //返回最小值 
    }
    
    int main() {
        
            int s, e;
            int size ;
            cin >> size >> n;
            
            //scanf ( "%d%d", &s, &e );
            for ( int i = 0; i <= n; i++ )
                for ( int j = 0; j <= n; j++ )
                    mp[i][j] = INF;
                    
            for(int i = 1;i <= n ; i++){
                int  x;
                cin >> p[i] >> l[i] >> x;
                
                for(int j = 1;j <= x; j++){
                    int t , v;
                    cin >> t >> v;
                    mp[i][t] = v;
                }
            }                
            minn = INF;
            int k = l[1];
                for(int i=0;i<=size;i++) //枚举 
        {
            memset(cha,false,sizeof(cha));
            for(int j=1;j<=n;j++)
            { //枚举等级允许的范围 
                if(l[j] >=k-size+i && l[j]<=k+i)
                    cha[j] = true;
            }
            
            minn = min(minn, dijkstra());
        }
      
          cout << minn << endl;
        
        return 0;
    }
  • 相关阅读:
    B题 hdu 1407 测试你是否和LTC水平一样高
    A题 hdu 1235 统计同成绩学生人数
    hdu 1869 六度分离(最短路floyd)
    hdu 2795 Billboard(线段树+单点更新)
    hdu 1754 I Hate It(线段树)
    hdu 1166敌兵布阵(线段树)
    hdu 1556(线段树之扫描线)
    Contest2073
    中南oj String and Arrays
    51nod 1459 迷宫游戏 (最短路径—Dijkstra算法)
  • 原文地址:https://www.cnblogs.com/DWVictor/p/11271422.html
Copyright © 2011-2022 走看看