• POJ


    POJ - 3159 题目链接

    思路:差分约束

    证明是最大值还是最小值的差分约束。

    由题意我们知道,A B C 表示 num(B) <= num(A) + C

    • 我们要使A B差值最大,我们就一定要取C刚好是其最大值
    • 由flymouse always compared the number of his candies with that of snoopy’s可知,
      我们的突破点就是这句话,我们要使flymose大于snoopy,而且snoopy一定是在第一个位置,于是我们设置snoopy的初始值是0,进行Dijkstra。
    • 题目就转换成了roadlenth[n] - roadlenth[1] = dis[n]
    • 为什么是最短路问题,num(B) <= num(A) + C 这里对应的正是最短路中的松弛过程,对这个条件跑一便最短路就行了

    代码

    //Powered by CK
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    typedef pair<int, int> PII;
    const int INF = 0x3f3f3f3f;
    const int N1 = 3e4 + 10, N2 = 15e4 + 10;
    int head[N1], to[N2], value[N2], nex[N2], cnt = 1;
    int visit[N1], dis[N1], n, m;
    struct cmp {
        bool operator () (const PII &a, const PII &b) const {
            return a.second > b.second;
        }
    };
    void add(int x, int y, int w) {
        to[cnt] = y;
        value[cnt] = w;
        nex[cnt] = head[x];
        head[x] = cnt++;
    }
    void Dijkstra() {
        for(int i = 1; i <= n; i++) visit[i] = 0, dis[i] = INF;
        priority_queue<PII, vector<PII>, cmp> q;
        dis[1] = 0;
        q.push(make_pair(1, 0));
        while(!q.empty()) {
            int temp = q.top().first;
            q.pop();
            if(visit[temp]) continue;
            visit[temp] = 1;
            for(int i = head[temp]; i; i = nex[i]) {
                if(dis[to[i]] > dis[temp] + value[i]) {
                    dis[to[i]] = dis[temp] + value[i];
                    q.push(make_pair(to[i], dis[to[i]]));
                }
            }
        }
        printf("%d
    ", dis[n]);
    }
    int main() {
        // freopen("in.txt", "r", stdin);
        int x, y, w;
        while(~scanf("%d %d", &n, &m)) {
            cnt = 1;
            memset(head, 0, sizeof head);
            for(int i = 0; i < m; i++) {
                scanf("%d %d %d", &x, &y, &w);
                add(x, y, w);
            }
            Dijkstra();
        }
        return 0;
    }
    

    写完题目后看了一下评论,说可以用栈的SPFA过

    就试着写了一个stack的spfa

    代码

    //Powered by CK
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<stack>
    using namespace std;
    typedef pair<int, int> PII;
    const int INF = 0x3f3f3f3f;
    const int N1 = 3e4 + 10, N2 = 15e4 + 10;
    int head[N1], to[N2], value[N2], nex[N2], cnt = 1;
    int visit[N1], dis[N1], n, m;
    struct cmp {
        bool operator () (const PII &a, const PII &b) const {
            return a.second > b.second;
        }
    };
    void add(int x, int y, int w) {
        to[cnt] = y;
        value[cnt] = w;
        nex[cnt] = head[x];
        head[x] = cnt++;
    }
    void spfa() {
        for(int i = 1; i <= n; i++) dis[i] = INF, visit[i] = 0;
        dis[1] = 0;
        stack<int> stk;
        stk.push(1);
        visit[1] = 1;
        while(!stk.empty()) {
            int temp = stk.top();
            stk.pop();
            visit[temp] = 0;
            for(int i = head[temp]; i; i = nex[i]) {
                if(dis[to[i]] > dis[temp] + value[i]) {
                    dis[to[i]] = dis[temp] + value[i];
                    if(!visit[to[i]])   stk.push(to[i]), visit[to[i]] = 1;
                }
            }
        }
    }
    int main() {
        // freopen("in.txt", "r", stdin);
        int x, y, w;
        while(~scanf("%d %d", &n, &m)) {
            cnt = 1;
            memset(head, 0, sizeof head);
            for(int i = 0; i < m; i++) {
                scanf("%d %d %d", &x, &y, &w);
                add(x, y, w);
            }
            spfa();
            printf("%d
    ", dis[n]);
        }
        return 0;
    }
    
  • 相关阅读:
    js:值类型/引用类型/内存回收/函数传值
    JS学习计划
    起点
    哈夫曼压缩/解压缩(控制台,C++)
    二维数组作为函数参数传递(C++)
    二级指针和指针引用函数传参(C++)
    学生管理系统(C++,控制台,文件读取,姓名排序)
    C++的getline()和get()函数
    二叉排序树节点的删除(C++,算法导论),前中后序遍历(递归/非递归,栈实现),按层次遍历(队列实现)
    QT程序打包成EXE
  • 原文地址:https://www.cnblogs.com/lifehappy/p/12626702.html
Copyright © 2020-2023  润新知