zoukankan      html  css  js  c++  java
  • POJ1062 昂贵的聘礼(最短路)

    题目链接

    分析:

    一开始以为简单的DFS,直接做,MLE了。

    本体应该用最短路径(Dijkstra算法)做。

    此题的关键在于等级限制的处理,采用枚举,即假设酋长等级为5,等级限制为2,那么需要枚举等级从3~5,4~6,5~7
    从满足改等级范围的结点组成的子图中用Dijkstra来算出最短路径,最后求出最小值。

    AC代码如下:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <queue>
    
    using namespace std;
    
    const int maxn = 100+10;
    const int INF = (1<<29);
    
    int G[maxn][maxn], level[maxn], val[maxn], n, d[maxn];
    bool lim[maxn];
    
    int dijkstra() {
        bool vis[maxn];
        memset(vis, false, sizeof(vis));
    
        for(int i=1; i<=n; i++) d[i] = INF;
        d[1] = 0;
    
        for(int i=1; i<n; i++) {
            int m = INF, x;
            for(int y=1; y<=n; y++) if(!vis[y] && lim[y] && m >= d[y]) m = d[x=y];
            vis[x] = true;
            for(int y=1; y<=n; y++) if(!vis[y] && lim[y] && d[y]>d[x]+G[x][y]) d[y] = d[x]+G[x][y];
        }
    
        int ans = INF;
        for(int i=1; i<=n; i++) {
            d[i] += val[i];
            ans = min(ans, d[i]);
        }
        return ans;
    }
    
    int main() {
        int p, l, x, t, v;
        int m;
        //freopen("my.txt", "r", stdin);
        while(scanf("%d%d", &m,&n) == 2) {
            for(int i=1; i<=n; i++) {
                for(int j=1; j<=n; j++) {
                    G[i][j] = INF;
                }
            }
    
            for(int i=1; i<=n; i++) {
                scanf("%d%d%d", &p, &l, &x);
                val[i] = p; level[i] = l;
    
                for(int j=0; j<x; j++) {
                    scanf("%d%d", &t, &v);
                    G[i][t] = v;
                }
            }
    
            int ans = INF;
    
            for(int i=0; i<=m; i++) {
                memset(lim, false, sizeof(lim));
                for(int j=1; j<=n; j++) {
                    if(level[j] >= level[1]-m+i && level[j] <= level[1]+i) lim[j] = true;
                }
    
                ans = min(ans, dijkstra());
            }
    
            printf("%d
    ", ans);
        }
    
        return 0;
    }
    View Code

    MLE代码也贴下。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <queue>
    
    using namespace std;
    
    const int maxn = 100+10;
    
    struct Edge {
        int nu, p, next;
    }ed[1000000];
    
    struct node {
        int p, l;
        int next;
    }head[maxn];
    
    int mem, m;
    
    void add(int u, int v, int p) {
        ed[mem].nu = v;
        ed[mem].p = p;
        ed[mem].next = head[u].next;
        head[u].next = mem++;   
    };
    
    int dfs(int u, int minv, int maxv) {
    
        int ans = head[u].p;
    
        for(int i=head[u].next; i != -1; i = ed[i].next) {
            int nmin = min(minv, head[ed[i].nu].l);
            int nmax = max(maxv, head[ed[i].nu].l);
            if(nmax - nmin > m) continue;
            if(ed[i].p >= ans) continue;
            ans = min(ans, ed[i].p + dfs(ed[i].nu, nmin, nmax));
        }
    
        return ans;
    }
    
    int main() {
        int n;
        int p, l, x, nu;
    
        //freopen("my.txt", "r", stdin);
        while(scanf("%d%d", &m,&n) == 2) {
            mem = 0;
    
            for(int i=1; i<=n; i++) {
                scanf("%d%d%d", &p, &l, &x);
    
                head[i].p = p; head[i].l = l; head[i].next = -1;
    
                for(int j=0; j<x; j++) {
                    scanf("%d%d", &nu, &p);
                    add(i, nu, p);
                }
            }
    
            printf("%d
    ", dfs(1, head[1].l, head[1].l));
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    settTimeout vs setInterval
    JS继承
    JS创建对象
    原型链
    开始学习python的感受
    Problem 29
    Python 查看关键字
    Problem 21
    Problem 34
    Problem 42
  • 原文地址:https://www.cnblogs.com/tanhehe/p/3158535.html
Copyright © 2011-2022 走看看