Arhus University 2000 - King (差分约束)

题目链接:传送门

题意:

  对题目中给定的si,ni,gi,ki,和一个给定的序列S[1....N],如果格式为(si,ni,gt,ki),意思就是新增一约束条件S[si]+S[si+1]+...S[si+ni]>ki,如果格式为(si,ni,lt,ki),意思就是新增一约束条件S[si]+S[si+1]+...S[si+ni]<ki,判断所给的约束条件有符合要求的序列S[1....N],有解就输出lamentable kingdom,无解就输出successful conspiracy。

题解:

  1. 对于gt,根据约束条件 S[si]+S[si+1]+...S[si+ni] > ki 可以列出 d[si+ni] - d[si-1] > ki ,即为 d[si-1] - d[si+ni] <= ki

  2. 对于lt ,根据约束条件 S[si]+S[si+1]+...S[si+ni] < ki 可以列出 d[si+ni] - d[si-1] < ki ,即为 d[si+ni] - d[si-1] <= ki - 1

  3. 新增点n+1,建立n+1到(1~n)的边,权值为0

  最后spfa判是否存在负环即可,条件为sum[to]>=n+2

代码:

  链式前向星&spfa

#include<bits/stdc++.h>
#define numm ch-48
#define pd putchar(' ')
#define pn putchar('\n')
#define pb push_back
#define fi first
#define se second
#define fre1 freopen("1.txt","r",stdin)
#define fre2 freopen("2.txt","w",stdout)
using namespace std;
template <typename T>
void read(T &res) {
    bool flag=false;char ch;
    while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true);
    for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);
    flag&&(res=-res);
}
template <typename T>
void write(T x) {
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
const int maxn=110;
const int inf=0x3f3f3f3f;
typedef long long ll;
struct edge {
    int to,w,net;
}edge[maxn];
int k,dis[maxn];
int sum[maxn],head[maxn],vis[maxn];
void init() {
    k=0;
    memset(head,-1,sizeof(head));
    memset(vis,false,sizeof(vis));
    memset(sum,0,sizeof(sum));
    memset(dis,inf,sizeof(dis));
}
void add(int u,int v,int w) {
    edge[++k].to=v;
    edge[k].w=w;
    edge[k].net=head[u];
    head[u]=k;
}
bool spfa(int n) {
    dis[n+1]=0,sum[n+1]++;
    queue<int>que;
    que.push(n+1);
    while(!que.empty()) {
        int k=que.front();
        que.pop();
        vis[k]=false;
        for(int i=head[k];i!=-1;i=edge[i].net) {
            if(dis[edge[i].to]>edge[i].w+dis[k]) {
                dis[edge[i].to]=edge[i].w+dis[k];
                if(!vis[edge[i].to]) {
                    if(++sum[edge[i].to]>=n+2) return false;
                    que.push(edge[i].to);
                    vis[edge[i].to]=true;
                }
            }
        }
    }
    return true;
}
int main()
{
    int n,m;
    while(scanf("%d",&n)!=EOF&&n) {
        read(m);
        init();
        for(int i=1;i<=m;i++) {
            int si,ni,ki;
            char oi[4];
            read(si),read(ni);
            scanf("%s",oi);
            read(ki);
            oi[0] == 'g' ? add(si+ni,si-1,-ki-1) : add(si-1,si+ni,ki-1);
        }
        for(int i=0;i<=n;i++)
            add(n+1,i,0);
//        puts("sadas");
        puts(spfa(n) ? "lamentable kingdom" : "successful conspiracy");
    }
    return 0;
}

  

posted @ 2019-07-16 13:03  wuliking  阅读(267)  评论(0编辑  收藏  举报