POJ - 3159 Candies

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\n", 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\n", dis[n]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lifehappy/p/12626702.html