zoukankan      html  css  js  c++  java
  • POJ

    http://poj.org/problem?id=1062

    题意:有100个物品,每个物品有一个价格值,一个地位值,和他可以用别的物品来补差价换。求换到1号物品的最小代价。

    意思就是给一个图,支付起点的点权,然后走边权走到1号点,求最小的代价,其中路上经过的地位值的差不能超过题目的限制。

    最暴力的做法,枚举地位的差,每次在反图上跑一次Dijkstra就好。这样貌似进行了多余的拷贝。

    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<map>
    #include<set>
    #include<stack>
    #include<string>
    #include<queue>
    #include<vector>
    using namespace std;
    typedef long long ll;
    
    vector<pair<int, int> >G0[105];
    vector<pair<int, int> >G[105];
    
    struct Item {
        int id;
        int st;
        int val;
    } item[105];
    
    int dis[105];
    bool vis[105];
    
    priority_queue<pair<int, int> > pq;
    void dijkstra(int s, int n) {
        while(!pq.empty())
            pq.pop();
        for(int i = 1; i <= n; ++i) {
            dis[i] = 0x3f3f3f3f;
            vis[i] = 0;
        }
        dis[s] = 0;
        pq.push({-dis[s], s});
        while(!pq.empty()) {
            int u = pq.top().second;
            pq.pop();
            if(vis[u])
                continue;
            vis[u] = 1;
            for(int i = 0; i < G[u].size(); ++i) {
                int v = G[u][i].first, w = G[u][i].second;
                if(dis[v] > dis[u] + w) {
                    dis[v] = dis[u] + w;
                    pq.push({-dis[v], v});
                }
            }
        }
    }
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        int m, n;
        scanf("%d%d", &m, &n);
        for(int i = 1; i <= n; ++i) {
            item[i].id = i;
            scanf("%d%d", &item[i].val, &item[i].st);
            int x;
            scanf("%d", &x);
            while(x--) {
                int v, w;
                scanf("%d%d", &v, &w);
                G0[i].push_back({v, w});
            }
        }
        int minval = 0x3f3f3f3f;
        for(int cst = item[1].st - m; cst <= item[1].st; ++cst) {
            for(int i = 1; i <= n; ++i)
                G[i].clear();
            int dst = cst + m;
            for(int i = 1; i <= n; ++i) {
                if(item[i].st >= cst && item[i].st <= dst) {
                    G[i] = G0[i];
                }
            }
    
            dijkstra(1, n);
            for(int i = 1; i <= n; ++i) {
                dis[i] += item[i].val;
                if(item[i].st >= cst && item[i].st <= dst)
                    minval = min(minval, dis[i]);
            }
        }
        printf("%d
    ", minval);
    }
    

    其实完全没有必要重新建图,Dijkstra里面标为vis的点之间不访问不更新就可以了。话说POJ这个抖动有点大啊。

    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<map>
    #include<set>
    #include<stack>
    #include<string>
    #include<queue>
    #include<vector>
    using namespace std;
    typedef long long ll;
    
    vector<pair<int, int> >G[105];
    
    struct Item {
        int id;
        int st;
        int val;
    } item[105];
    
    int dis[105];
    bool vis[105];
    
    priority_queue<pair<int, int> > pq;
    void dijkstra(int s, int n, int cst, int dst) {
        while(!pq.empty())
            pq.pop();
        for(int i = 1; i <= n; ++i) {
            dis[i] = 0x3f3f3f3f;
            vis[i] = !(item[i].st >= cst && item[i].st <= dst);
        }
        dis[s] = 0;
        pq.push({-dis[s], s});
        while(!pq.empty()) {
            int u = pq.top().second;
            pq.pop();
            if(vis[u])
                continue;
            vis[u] = 1;
            for(int i = 0; i < G[u].size(); ++i) {
                int v = G[u][i].first, w = G[u][i].second;
                if(!vis[v] && dis[v] > dis[u] + w) {
                    dis[v] = dis[u] + w;
                    pq.push({-dis[v], v});
                }
            }
        }
    }
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        int m, n;
        scanf("%d%d", &m, &n);
        for(int i = 1; i <= n; ++i) {
            item[i].id = i;
            scanf("%d%d", &item[i].val, &item[i].st);
            int x;
            scanf("%d", &x);
            while(x--) {
                int v, w;
                scanf("%d%d", &v, &w);
                G[i].push_back({v, w});
            }
        }
        int minval = 0x3f3f3f3f;
        for(int cst = item[1].st - m; cst <= item[1].st; ++cst) {
            int dst = cst + m;
            dijkstra(1, n, cst, dst);
            for(int i = 1; i <= n; ++i)
                minval = min(minval, dis[i] + item[i].val);
        }
        printf("%d
    ", minval);
    }
    
  • 相关阅读:
    javascript中数组去重的4种方法
    dede使用方法----实现英文版的搜索功能
    dede去掉当前位置position后面的箭头
    dede使用方法----如何转换时间戳
    Python字符串、元组、列表、字典互相转换的方法
    Python 列表的操作
    Python 元祖的操作
    Python 操作文件、文件夹、目录大全
    python文件目录操作大全
    python用time函数计算程序运行时间
  • 原文地址:https://www.cnblogs.com/Inko/p/11715263.html
Copyright © 2011-2022 走看看