zoukankan      html  css  js  c++  java
  • POJ1364 King 差分约束

    题意:和上一题比较像,不过这里不是根据已知的约束求出另外一个约束,而是判定是否存在解。给定一个区间的和值区间,问整个区间能否满足所有的要求。

    解法:虚拟一个超级源点,超级源点到点i的最短路表示到第i个数时总和为dis[i],为了保证每个点能够被计算到,那么需要从超级源点连一条没有什么影响的边出来。然后对整个图求一次spfa,观察是否存在负环。

    代码如下:

    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    int N, M, idx;
    int head[105];
    const int T = 102; // 超级源点 
    
    struct Edge {
        int v, ct, next;
    }e[505];
    
    void insert(int a, int b, int ct) {
        e[idx].v = b, e[idx].ct = ct;
        e[idx].next = head[a];
        head[a] = idx++;
    }
    
    #include <queue>
    int dis[105], cnt[105];
    char vis[105];
    
    bool spfa() {
        memset(dis, 0x3f, sizeof (dis));
        memset(cnt, 0, sizeof (cnt));
        memset(vis, 0, sizeof (vis));
        queue<int>q;
        q.push(T);
        cnt[T] = 1, vis[T] = 1, dis[T] = 0;
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            vis[v] = 0;
            if (cnt[v] > N+5) return false;
            for (int i = head[v]; i != -1; i = e[i].next) {
                if (dis[e[i].v] > dis[v] + e[i].ct) {
                    dis[e[i].v] = dis[v] + e[i].ct;
                    if (!vis[e[i].v]) {
                        q.push(e[i].v);
                        ++cnt[e[i].v];
                        vis[e[i].v] = 1;
                    }
                }    
            }
        }
        return true;
    }
    
    int main() {
        int a, b, c;
        char op[5];
        while (scanf("%d", &N), N) {
            idx = 0;
            memset(head, 0xff, sizeof (head));
            scanf("%d", &M);
            for (int i = 0; i < M; ++i) {
                scanf("%d %d %s %d", &a, &b, op, &c);
                if (op[0] == 'g') { // dis[b] - dis[a-1] >= c+1
                    insert(a+b, a-1, -c-1);
                } else { // dis[b] - dis[a-1] <= c-1
                    insert(a-1, a+b, c-1);
                }
            }
            for (int i = 0; i <= N; ++i) {
                insert(T, i, rand() % 1000);
                // 引入一条从超级源点到任意一点的0边,这个约束条件对题解没有影响 
            }
            if (spfa()) {
                puts("lamentable kingdom");
            } else {
                puts("successful conspiracy");
            }
        }
        return 0;    
    }
  • 相关阅读:
    js 小数乘积位数太长
    微信浏览器跳转外部浏览器 app下载
    linux 查询制定目录的制定内容
    windows apache 跳转 tomcat 代理
    windows版 nginx配置反向代理实例教程 跳转tomcat和php网站
    概率论公式
    Python scipy 计算短时傅里叶变换(Short-time Fourier transforms)
    Centos 解决SSH 免密码登录 以及Crontab制作定时SSH自动登录和关闭的脚本
    python3 日志检索异常抛出异常 raise KeyError(key),KeyError: 'formatters'
    Pthon Matplotlib 画图
  • 原文地址:https://www.cnblogs.com/Lyush/p/2959416.html
Copyright © 2011-2022 走看看