POJ 1364[差分约束]

题目链接:【http://poj.org/problem?id=1364】

晕死了。但是也长知识了

题意:一个长度为n的序列:a[1]、a[2]、a[3]...a[n],然后给你一些约束条件:si、ni、gt||lt、ki表示:a[si]、a[si+1]、、、、a[si+ni]<or>ki,问你满足这些约束条件,字符串是否存在。存在输出:lamentable kingdom,否则输出:successful conspiracy

题解:对序列求前缀和,将约束条件改为:sum[si+ni]-sum[si-1]<or>ki,为了方便:我们使其小标从1开始:sum[si+ni+1]-sum[si]<or>ki;

但是:虽然我们可以根据上面的约束关系建立图,但是并不能保证图的联通,也就是说我们不一定能找到负环,我们可以对所有的点在加入一个相同的约束关系(这样做并不会影响最终的约束关系,但但是增加了图的连通性),添加约束关系的时候我们有两种方案:

1、建立超级点,这个超级点1和任意一个点的约束关系都一样。

2、在用SPFA求负环的时候,把所有的点加入队列并把dis[]初始化为零,(相当于建立了一个超级起点),然后判断是否有点入队的的次数大于N即可;

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 150;
int N, M;
int u, v, d;
char s[15];
struct Edge
{
    int id, next, len;
    Edge(int id = 0, int next = 0, int len = 0): id(id), next(next), len(len) {}
} E[maxn];
int head[maxn], tot;
void init()
{
    memset(head, -1, sizeof(head));
    tot = 0;
}
void adde(int u, int v, int len)
{
    E[tot] = Edge{v, head[u], len};
    head[u] = tot++;
}
int top, stk[maxn], num[maxn];
int dis[maxn], vis[maxn];
bool SPFA(int st, int N)
{
    for(int i = 0; i <= N; i++)
        dis[i] = 0, vis[i] = 1, num[i] = 0;;
    for(int i = 0; i < N; i++)
        stk[i] = i + 1;
    top = N + 1;
    while(top)
    {
        int u = stk[--top];
        vis[u] = 0;
        for(int k = head[u]; ~k; k = E[k].next)
        {
            int v = E[k].id;
            if(dis[v] > dis[u] + E[k].len)
            {
                dis[v] = dis[u] + E[k].len;
                if(vis[v]) continue;
                vis[v] = 1;
                stk[top++] = v;
                num[v]++;
                if(num[v] > N) return false;
            }
        }
    }
    return true;
}
int main ()
{
    while(scanf("%d", &N), N)
    {
        init();
        scanf("%d", &M);
        for(int i = 1; i <= M; i++)
        {
            scanf("%d %d %s %d", &u, &v, s, &d);
            if(s[0] == ‘l‘)
                adde(u, u + v + 1, d - 1);//保证下标从1开始
            else
                adde(u + v + 1, u, -d - 1);//变成 " <= ";
        }
        bool ans = SPFA(1, N + 1);
        if(!ans) printf("successful conspiracy\n");
        else    printf("lamentable kingdom\n");
    }
    return 0;
}
时间: 2024-11-18 12:20:26

POJ 1364[差分约束]的相关文章

poj 1364差分约束

King Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 10206   Accepted: 3777 Description Once, in one kingdom, there was a queen and that queen was expecting a baby. The queen prayed: ``If my child was a son and if only he was a sound kin

poj 3169 差分约束

3169 差分约束的是满足多组形如xi-yj<=bk{i,j<n k<m}不等式极值问题,可以转化为单源最短路来求. 在最短路中 d[v]<=d[u]+w(u,v) 可以看出跟上面的不等式很像 通常有两种一种是求满足所有不等式的最大值,还有是最小值. 这篇博客可以参考一下 分析: 题目给出了两种不等式  d[u]+dl >=d[v]       d[u]+dd<=d[v]  要求的是最大值,也就是最短路 对于d[u]+dl>=d[v] 建边(u,vdl) 对于d[

POJ 3159[差分约束]

题目链接:[http://poj.org/problem?id=3159] 题意:有N个小朋友,编号为1-N,每个小朋友将分的一些糖果,给出一些关系A.B.C .表示B最多比A多C个,然后问你盆友1和盆友N的糖果数最大差多少.保证有解. 题解:差分约束求最短距离:DIJ+对优化||SPAF+栈优化 #include<queue> #include<cstdio> #include<cstring> #include<algorithm> using name

hdu 1364(差分约束)

King Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12056   Accepted: 4397 Description Once, in one kingdom, there was a queen and that queen was expecting a baby. The queen prayed: ``If my child was a son and if only he was a sound kin

poj 1201(差分约束)

Intervals Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 24948   Accepted: 9491 Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a program that: reads the number of intervals, their end po

poj 1201 差分约束+spfa

非常经典的差分约束系统的建模.求最小值需要转化为求最长路. 1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 using namespace std; 6 7 const int INF = 99999999; 8 const int N = 50002; 9 const int M = 200000; 10 int head[N];

poj 3159 差分约束+spfa

由于此题数据特殊,队列优化的spfa会超时,可以改成用栈来优化. 1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 using namespace std; 6 7 const int INF = 9999999; 8 const int N = 30001; 9 const int M = 150000; 10 int head[N

POJ 1364 King --差分约束第一题

题意:求给定的一组不等式是否有解,不等式要么是:SUM(Xi) (a<=i<=b) > k (1) 要么是 SUM(Xi) (a<=i<=b) < k (2) 分析:典型差分约束题,变换,令Ti = SUM(Xj) (0<=j<=i).  则表达式(1)可以看做T(a+b)-T(a-1) > k,也就是T(a-1)-T(a+b) < -k,又因为全是整数,所以T(a-1)-T(a+b) <= -k-1.  同理,(2)看做T(a+b)-T(

POJ 1364 King 差分约束 找负环

嘛,虽然是一道水题+模板题,不过还是学到了很多东西的,记录一下. 首先题目给出的不等式是小于,但是差分约束系统只能处理小于等于的情况,所以要转化成小于等于的进行处理.对于整数处理方法非常简单= = 然后是找负环的情况,其实不需要考虑图连不连通,只要一开始就把所有的点的d置成0,然后都push进队列里面就好了. PS:这种方法同样可以用在处理多源点最短路问题上. #include <cstdio> #include <cstring> #include <cmath> #