zoukankan      html  css  js  c++  java
  • poj3169

    差分约束系统

    差分约束系统有两种方式可以求解,最短路和最长路。当我们把不等式整理成d[a]+w<=d[b]时,我们求最长路。整理成d[a]+w>=d[b]时,我们求最短路。当求最短路时,我们通常要把各点距离初始化为正无穷,求最短路,把各点距离逐渐减小,直到符合所有不等式。也就是开始各点不符合条件,后来通过减小变得符合了,所以一定是符合条件的最大值。既然是求最大值,并且是减小各点距离,也就是把各点由数轴的右侧向左侧拉,所以我们一定要选择一个最终在数轴最左侧的点,并初始化为0,把所有正无穷的点拉近到符合不等式。最长路同理。

    另外本题我的做法判断impossible的情况是不完全的,暂未发现谁处理得比较正确。我的代码只能判断起点可达的点是否有负环。

    View Code
    #include <iostream>
    #include
    <cstdlib>
    #include
    <cstring>
    #include
    <cstdio>
    #include
    <queue>
    using namespace std;

    #define INF 0x3f3f3f3f
    #define V 1005
    #define E 20001

    int pnt[E], cost[E], nxt[E];
    int e, head[V], dist[V];
    bool vis[V];
    int cnt[V];

    int relax(int u, int v, int c)
    {
    if (dist[v] > dist[u] + c)
    {
    dist[v]
    = dist[u] + c;
    return 1;
    }
    return 0;
    }

    inline
    void addedge(int u, int v, int c)
    {
    pnt[e]
    = v;
    cost[e]
    = c;
    nxt[e]
    = head[u];
    head[u]
    = e++;
    }

    int SPFA(int src, int n)
    {
    int i;
    memset(cnt,
    0, sizeof(cnt));
    memset(vis,
    false, sizeof(vis));
    for (i = 1; i <= n; ++i)
    dist[i]
    = INF;
    dist[src]
    = 0;
    queue
    <int> Q;
    Q.push(src);
    vis[src]
    = true;
    ++cnt[src];
    while (!Q.empty())
    {
    int u, v;
    u
    = Q.front();
    Q.pop();
    vis[u]
    = false;
    for (i = head[u]; i != -1; i = nxt[i])
    {
    v
    = pnt[i];
    if (1 == relax(u, v, cost[i]) && !vis[v])
    {
    Q.push(v);
    vis[v]
    = true;
    if ((++cnt[v]) > n)
    return -1;
    }
    }
    }
    if (dist[n] == INF)
    return -2;
    return dist[n];
    }

    int main()
    {
    //freopen("t.txt", "r", stdin);
    int n, ml, md;
    int i, a, b, c;
    e
    = 0;
    scanf(
    "%d%d%d", &n, &ml, &md);
    memset(head,
    -1, sizeof(head));
    for (i = 0; i < ml; ++i)
    {
    scanf(
    "%d%d%d", &a, &b, &c);
    addedge(a, b, c);
    }
    for (i = 0; i < md; ++i)
    {
    scanf(
    "%d%d%d", &a, &b, &c);
    addedge(b, a,
    -c);
    }
    printf(
    "%d\n", SPFA(1, n));
    return 0;
    }
  • 相关阅读:
    感动女友的话
    情侣一起玩的游戏
    让妹子被我征服
    调戏妹子 微信聊天
    sqlserver2008 解决 ldf文件过大的方法
    sqlserver 动态表名 动态字段名 执行 动态sql
    sqlserver convert 日期时间 转换格式化
    sqlserver 2008 卸载时提示 “重新启动计算机”失败
    sqlserver mdf ldf文件导入
    myeclipse trial expired[转]
  • 原文地址:https://www.cnblogs.com/rainydays/p/2178895.html
Copyright © 2011-2022 走看看