POJ 1364 差分约束

思路:
把所有“>”变成“≥”
把所有“<”变成“≤”

(加一减一就好了)

然后我们发现:图不一定连通!!

怎么办呢

对于每一个连通块SPFA就好了嘛……

//By SiriusRen
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 111
using namespace std;
char a[3],inq[N];
int n,vis[N],xx,yy,zz,m,dis[N],cnt[N];
int first[N],next[N*N],v[N*N],w[N*N],tot=0;
void add(int x,int y,int z){w[tot]=z,v[tot]=y,next[tot]=first[x],first[x]=tot++;}
bool spfa(int x){
    memset(cnt,0,sizeof(cnt));
    memset(dis,0xcf,sizeof(dis));
    memset(inq,0,sizeof(inq));
    dis[x]=0;vis[x]=cnt[x]=1;
    queue<int>q;q.push(x);
    while(!q.empty()){
        int t=q.front();q.pop();
        inq[t]=0;vis[t]=1;
        for(int i=first[t];~i;i=next[i])
            if(dis[v[i]]<dis[t]+w[i]){
                dis[v[i]]=dis[t]+w[i];
                if(!inq[v[i]]){
                    inq[v[i]]=1;
                    cnt[v[i]]++;q.push(v[i]);
                    if(cnt[v[i]]>n)return 0;
                }
            }
    }
    return 1;
}
int main(){
    scanf("%d",&n);
    start:memset(first,-1,sizeof(first));
    memset(vis,0,sizeof(vis));
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d%s%d",&xx,&yy,a,&zz);
        if(a[0]=='g')add(xx-1,xx+yy,zz+1);
        else add(xx+yy,xx-1,-zz+1);
    }
    for(int i=0;i<=n;i++){
        if(vis[i])continue;
        if(!spfa(i)){
            puts("successful conspiracy");
            goto end;
        }
    }
    puts("lamentable kingdom");
    end:if(scanf("%d",&n)&&n)goto start;
}

这里写图片描述

原文地址:https://www.cnblogs.com/SiriusRen/p/6532318.html