POJ 1364 King[差分约束]

题目链接:http://poj.org/problem?id=1364
题目大意:是否存在一个序列满足给的m组条件
si ni oi ki
如果oi=gt 表示:S(i+ni)-Si>ki
如果oi=lt 表示:S(i+ni)-Si<ki
由于查分约束的特点要变成x-y<=z的形势,因此对于上面的式子变形:
oi=gt ---> S(i+ni)-Si<=-ki-1
oi=lt ---> Si-S(i+ni)<=ki-1
然后建图,用spfa求最短路

代码如下:

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define N 100000
#define M 100000
#define INF 999999999
int dis[N]; //记录距离
int vis[N];  //标记是否在队列中
int queue[N]; //模拟队列
int outqueue[N]; //记录点i出队的次数
int head[N];
int index, n; //index记录head[] s:源点 n个点

struct Edge
{
    int v, next, value;
}edge[M];

void add_Edge(int u, int v, int val)
{
    edge[index].next=head[u];
    edge[index].v=v;
    edge[index].value=val;
    head[u]=index++;
}

int Spfa(int s)
{
    int iq=0, front=0, i, top;
    memset(vis, 0, sizeof(vis));
    memset(outqueue, 0, sizeof(outqueue));
    for(i=0; i<=n; i++)
        dis[i]=INF;
    dis[s]=0;
    queue[iq++]=s;
    vis[s]=1;
    while(iq!=front)
    {
        top=queue[front];
        front++;
        vis[top]=0;
        outqueue[top]++;
        if(outqueue[top]>n)  return 0;
        for(i=head[top]; i!=-1; i=edge[i].next)
        {
            if(dis[top]+edge[i].value<dis[edge[i].v])
            {
                dis[edge[i].v]=dis[top]+edge[i].value;
                if(vis[edge[i].v]==0)
                {
                    vis[edge[i].v]=1;
                    queue[iq++]=edge[i].v;
                }
            }
        }
    }
    return 1;
}
int main()
{
    int si, ki, i, ni, m;
    char ch[5];
    while(scanf("%d", &n), n)
    {
        scanf("%d", &m);
        index=0;
        memset(head, -1, sizeof(head));
        for(i=0; i<m; i++)
        {
            scanf("%d %d %s %d", &si, &ni, ch, &ki);
            if(ch[0]=='g')
                add_Edge(ni+si, si-1, -ki-1);
            else
                add_Edge(si-1, ni+si, ki-1);
        }
        for(i=1; i<=n; ++i)  //i=0开始一直wa...wa死我了...泪奔TT...
            add_Edge(n+1, i, 0);
        if(Spfa(n+1))
            printf("lamentable kingdom
");
        else
            printf("successful conspiracy
");
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/Hilda/p/3226704.html