POJ 1364

  这是一道差分约束系统的题目。所给的约束条件是对于一个序列的子序列来说,子序列的和大于或小于一个数,问是否存在一个序列,使得所有约束条件全部成立。

  我采用用数列中类似于数列求和的方式,比如序列a1,a2,a3....令s1=a1,s2=a1+a2,s3=a1+a2+a3...为了方便,我还引入了s0=0,这样就可以根据题目的条件列出不等式,再把不等式转化为求最短路的问题。开始我想当然地认为si>=si-1(i和i-1为下标),加了这个条件之后当然是错的,后来发现了这个问题,将其去掉,但是却忽略了一点:这道题其实是让我判断是否存在负环。因为图可能不连通,所以应该每个点都要作为一次起点,用SPFA求最短路,发现负环则跳出。

  总之,大体思路的方向是对的,仍然是细节需要注意。

#include<stdio.h>
#include<string.h>

#define INF 100000000
#define MAX_VERTEX 110
#define MAX_QUE 100000

int graphic[MAX_VERTEX][MAX_VERTEX];
int dist[MAX_VERTEX];

int spfa(int,int,int);
inline void ini(int);

int main()
{
    int n,m;
    while(scanf("%d",&n)!=EOF&&n!=0)
    {
        getchar();
        scanf("%d",&m);
        ini(n+1);

        int i=0;
        for(i=0;i<m;i++)
        {
            int stt,toEnd,delta;
            char ope[3];
            scanf("%d%d%s%d",&stt,&toEnd,ope,&delta);
            if(ope[0]=='l')
            {
                graphic[stt-1][stt+toEnd]=delta-1;
            }
            else
            {
                graphic[stt+toEnd][stt-1]=-1-delta;
            }
        }

        int flag=1;
        for(i=0;i<n;i++)
        {
            flag=spfa(i,n,n+1);
            if(flag==0)
                break;
        }
        if(flag)
        {
            printf("lamentable kingdom\n");
        }
        else
        {
            printf("successful conspiracy\n");
        }
    }
    return 0;
}

int spfa(int stt,int end,int lmt)
{
    int front=0,rear=1,que_num;
    int que[MAX_QUE],in_or_not[MAX_VERTEX],inque_times[MAX_VERTEX];

    int i=0;
    for(i=0;i<lmt;i++)
        dist[i]=INF;
    memset(in_or_not,0,sizeof(in_or_not));
    memset(inque_times,0,sizeof(inque_times));

    que[front]=stt;
    que_num=1;
    in_or_not[stt]=1;
    dist[stt]=0;
    inque_times[stt]=1;

    while(que_num!=0)
    {
        int now_where=que[front];
        in_or_not[now_where]=0;
        que_num--;

        int i;
        for(i=0;i<lmt;i++)
        {
            int len=graphic[now_where][i];

            if(i!=now_where&&len!=INF&&dist[now_where]+len<dist[i])
            {
                dist[i]=dist[now_where]+len;
                if(in_or_not[i]==0)
                {
                    in_or_not[i]=1;
                    inque_times[i]++;

                    if(inque_times[i]>lmt)
                        return 0;

                    que[rear]=i;
                    if(rear+1==MAX_QUE)
                        rear=0;
                    else
                        rear++;
                    que_num++;
                }
            }
        }
        if(front+1==MAX_QUE)
            front=0;
        else
            front++;
    }
    return 1;
}

inline void ini(int lmt)
{
    int i,j;
    for(i=0;i<lmt;i++)
    {
        for(j=0;j<lmt;j++)
        {
            graphic[i][j]=INF;
        }
    }
}
posted @ 2012-08-17 19:36  等待电子的砹  阅读(437)  评论(0编辑  收藏  举报