POJ3169

来源:互联网 发布:网络结构图 visio 编辑:程序博客网 时间:2024/06/05 06:34

题目链接:

https://cn.vjudge.net/problem/POJ-3169


题目大意:

这里写图片描述


解题过程:

刚开始是一脸懵逼的,怎么还有这种题,完全没想法。
然后看书上说是差分约束,然后和最短路类比了下,还是没看懂,最后是去网上搜了下博客,然后又自己画了画才弄懂。

http://www.cppblog.com/menjitianya/archive/2015/11/19/212292.html


题目分析:

关于最短路,设函数 d(v) 的含义是从起点到节点 v 的最短距离,那么对于任意权值为 w 的边 e = (u, v) ,都有 d(u) + w >= d(v) 成立,公式可化为 w >= d(v) - d(u) 。最短路就是求解这组方程,变量是 d(v/x) ,求解这组方程就是意味着求出满足方程的 d(v) - d(u) 的最大值。

对于这个题目,有三个约束条件,第一个是牛按编号顺序排,第二个是某两头牛之间的距离不能大于一个值,第三个是某两头牛之间的距离必须不小于一个值。

假设这两头牛分别是 uv(v > u),约束距离是 w ,对于第一个条件, d(v) - d(u) >= 0d(v) + 0 >= d(u) ,从vu建一条权值为 0 的边。

对于第二个条件,d(u) + w >= d(v),即从 uv 建一条权值为 w 的边。

对于第三个条件,d(u) + w <= d(v)d(v) - w >= d(u),从 vu 建一条权值为 -w 的边。

然后对于上面所建立的图,求出从起点到节点的最短距离即是答案。

如果这个图无法联通,表示没有可行的方案。如果存在负环,那么这个距离是可以无限大的。

AC代码:

#include <vector>#include <cstring>#include <queue>#include <cstdio>using namespace std;const int MAX = 11234, INF = 0x3f3f3f3f;int frequency[MAX], dist[MAX], vis[MAX];int N, ML, MD;vector<pair<int, int> > edge[MAX];int spfa() {    memset(dist, INF, sizeof(dist));    queue<int> q;    q.push(1);    dist[1] = 0;    while (!q.empty()) {        int u = q.front();        q.pop();        vis[u] = 0;        for (int i = 0; i < edge[u].size(); i++) {            int v = edge[u][i].first;            int w = edge[u][i].second;            if (dist[v] > dist[u] + w) {                dist[v] = dist[u] + w;                if (!vis[v]) {                    vis[v] = 1;                    frequency[v]++;                    if (frequency[v] > N)                        return -INF;                    q.push(v);                }            }        }    }    return dist[N];}int main() {    scanf("%d %d %d", &N, &ML, &MD);    int u, v, w;    for (int i = 2; i <= N; i++) {        edge[i].push_back(make_pair(i-1, 0));    }    for (int i = 0; i < ML; i++) {        scanf("%d %d %d", &u, &v, &w);        edge[u].push_back(make_pair(v, w));    }    for (int i = 0; i < MD; i++) {        scanf("%d %d %d", &u, &v, &w);        edge[v].push_back(make_pair(u, -w));    }    int ans = spfa();    if (ans <= -INF) {        printf("-1\n");    }    else if (ans >= INF) {        printf("-2\n");    }    else {        printf("%d\n", ans);    }}
0 0
原创粉丝点击