POJ1364 King

来源:互联网 发布:c语言delay函数 编辑:程序博客网 时间:2024/06/04 17:46

差分约束

题目传送门

题目大意:已知一个连续的数列a[i],给你这个数列的一些约束条件(如a[i]+a[i+1]+……+a[i+s]大于或小于k)以及这个数列的长度,问是否存在这样一个数列满足上述条件,若有则输出lamentable kingdom,否则输出successful conspiracy。

典型的差分约束,约束条件题目已经给定。由于只需判断是否有解,因此跑最长路或最短路都可以。注意符号即可。

最短路的约束条件:
a[si-1] - a[si+ni] <= - ki - 1
a[si+ni] - a[si-1] <= ki - 1

贴上代码(我因为spfa写错RE了好多次。。。。):

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct edge{    int next;    int to;    int dis;};int n,m,k;int h[105],dis[505];bool f[105];bool flag;edge a[100005];char s1,s2;void read(int x,int y,int z){    k++;    a[k].next=h[x];    a[k].to=y;    a[k].dis=z;    h[x]=k;}void spfa(){    memset(dis,0x7f,sizeof(dis));    memset(f,false,sizeof(f));    flag=false;    int b[100000]={0};    int r=0,w=1;    b[1]=0; f[0]=true;    dis[0]=0;    while (r<w){        int x=b[++r];        f[x]=false;        for (int i=h[x];i;i=a[i].next)            if (dis[a[i].to]>dis[x]+a[i].dis){                dis[a[i].to]=dis[x]+a[i].dis;                if (!f[a[i].to]){                    b[++w]=a[i].to;                    f[a[i].to]=true;                    if (w>90000){                            flag=true;                            break;                        }                }            }        if (flag)            break;    }}int main(){    while (scanf("%d",&n)&&n){        scanf("%d",&m);        memset(h,0,sizeof(h));        k=0;        for (int i=1;i<=m;i++){            int x,y,z;            scanf("%d %d %c%c %d",&x,&y,&s1,&s2,&z);            if (s1=='g')                read(x+y+1,x,-z-1);            else                read(x,x+y+1,z-1);        }        for (int i=1;i<=n+1;i++)            read(0,i,0);        spfa();        if (flag)            printf("successful conspiracy\n");        else             printf("lamentable kingdom\n");    }    return 0;}