POJ - 3169Layout差分約束+spfa

Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a straight line waiting for feed. The cows are standing in the same order as they are numbered, and since they can be rather pushy, it is possible that two or more cows can line up at exactly the same location (that is, if we think of each cow as being located at some coordinate on a number line, then it is possible for two or more cows to share the same coordinate).
在進行差分約束時把b-a<=m可以看做從a指向b做一條權值爲m的邊。建圖時要求所有點之間的關係都是b-a<=m的形式。遇到b-a>=m時可轉化成a-b<=-m。
以上兩種關係加上一個a[i+1]-a[i]>=0的關係,可以建圖。
邊值可能爲負,這裏用spfa求解。

#include<queue>
#include<stdio.h>
#include<string>
#include<iostream>
#include<map>
#include<limits>
#include<math.h>

using namespace std;
#define N 20000+5
#define LL long long int
#define pow(a) ((a)*(a))
#define INF 0x3f3f3f3f
#define mem(arr,a) memset(arr,a,sizeof(arr))
int n, a, b;
int d[N];
int edgelist[N];
int vis[N];
int num[N];
int Q[N];
struct edge{
    int v, w;
    int next;
};
edge es[N];
int top = -1;
void spfa(){
    mem(d, INF);
    d[1] = 0;
    Q[++top] = 1;
    while (top != -1){
        int x = Q[top]; top--; vis[x] = 0;
        for (int i = edgelist[x]; i != -1; i = es[i].next){
            edge e = es[i];
            if (d[e.v] > d[x] + e.w){
                d[e.v] = d[x] + e.w;
                if (!vis[e.v]){
                    vis[e.v] = 1;
                    Q[++top] = e.v;
                    num[e.v]++;
                    if (num[e.v] == n){
                        cout << -1 << endl;
                        return;
                    }
                }
            }
        }
    }
    if (d[n] == INF)cout << -2 << endl;
    else cout << d[n] << endl;
}
void add(int from, int to, int dis,int i){
    es[i].v = to;
    es[i].w = dis;
    es[i].next = edgelist[from];
    edgelist[from] = i;
}
int main(){
    cin >> n >> a >> b;
    mem(edgelist, -1);
    int k = 1;
    for (int i = 0; i < a; i++){
        int from, to, MAX;
        scanf("%d%d%d", &from, &to, &MAX);
        if (from>to)swap(from, to);
        add(from, to, MAX, k);
        k++;
    }
    for (int i = 0; i < b; i++){
        int from, to, MIN;
        scanf("%d%d%d", &from, &to, &MIN);
        if (from>to)swap(from, to);
        add(to, from, -MIN, k);
        k++;
    }
    for (int i = 0; i < n - 1; i++){
        add(i+1, i, 0, k);
        k++;
    }
    es;
    spfa();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章