POJ2983 Is the Information Reliable?(差分约束)

题意:敌国有N个防御工事,排在一条直线上。你截获了M条情报,有的精确(P)有的模糊(V)。P情报有三个值A,B,X,表示A站点在B站点北部X距离处。V情报有两个值A,B,表示A在B北方,至少相隔1距离。判断这些情报汇总起来是否有解。

思路:N个点都在一条数轴上,设向北为正方向,Sa代表a在数轴上的相对坐标,对于V情报,有 Va - Vb >= 1.

对于P情报,可以构造 Sa - Sb >= X 和 Sa - Sb <= X 两个不等式。

因为要求是否有解,求最大距离和最小距离均可,本题用最短路求最长距离。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <cstdlib>
#include <set>
#include <string>

using namespace std;

typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1005;
struct edg{
    int v, w, nxt;
}G[maxn * 200];
int tot, pre[maxn];
void add(int u, int v, int w) {
    G[tot].v = v;
    G[tot].w = w;
    G[tot].nxt = pre[u];
    pre[u] = tot++;
}
int n, m;
int dis[maxn], times[maxn];
bool vis[maxn];
bool spfa() {
    queue<int> que;
    for (int i = 1; i <= n; ++i) {
        vis[i] = true;
        que.push(i);
        dis[i] = inf;
        times[i] = 1;
    }
    dis[1] = 0;
    while (!que.empty()) {
        int u = que.front();
        que.pop();
        vis[u] = false;
        for (int i = pre[u]; ~i; i = G[i].nxt) {
            int v = G[i].v, w = G[i].w;
            if (dis[u] + w < dis[v]) {
                dis[v] = dis[u] + w;
                if (!vis[v]) {
                    if (++times[v] > n) {
                        return false;
                    }
                    que.push(v);
                    vis[v] = true;
                }
            }
        }
    }
    return true;
}
int main(){
    int a, b, c;
    char ch;
    while (~scanf("%d%d", &n, &m)) {
        getchar();
        tot = 0;
        memset(pre, -1, sizeof(pre));
        while (m--) {
            scanf("%c", &ch);
            if (ch == 'P') {
                scanf("%d%d%d", &a, &b, &c);
                add(a, b, -c);
                add(b, a, c);
            } else {
                scanf("%d%d", &a, &b);
                add(a, b, -1);
            }
            getchar();
        }
        if (spfa()) {
            puts("Reliable");
        } else {
            puts("Unreliable");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hcx11333/article/details/81481595