POJ

来源:互联网 发布:矩阵理论 张跃辉答案 编辑:程序博客网 时间:2024/06/05 08:38

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();}
原创粉丝点击