poj 1364 King(差分约束)

时间:2023-03-08 23:23:45
poj 1364 King(差分约束)

题意(真坑):傻国王只会求和,以及比较大小。阴谋家们想推翻他,于是想坑他,上交了一串长度为n的序列a[1],a[2]...a[n],国王作出m条形如(a[si]+a[si+1]+...+a[si+ni])>k(或<k)的批示,结果发现批错了,问是否存在一个满足不等式组的序列a[1]...a[n],好让国王借口自己看错了。

因为是求是否存在,即判环,没有要求最大还是最小,所以最长路、最短路都可以解决。

注意:

1、总点数,若不加源点而采用把所有点入队,总点数==n+1;否则,总点数==n+2。这影响到cnt[]>n还是cnt[]>(n+1)。

2、差分约束求解的是>=以及<=的问题,这里的>(或<)可以变化一下,>k等价于>=(k+1)。

 #include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define clr(a,m) memset(a,m,sizeof(a))
using namespace std; const int MAXN=;//经尝试,MAXN==49就能过,poj的数据真水
const int INF =MAXN; struct Edge{
int v,c,next;
Edge(){}
Edge(int _v,int _c,int _next):v(_v),c(_c),next(_next){}
}edge[MAXN<<]; int head[MAXN],tol;
int d[MAXN],inq[MAXN],cnt[MAXN]; void init()
{
tol=;
clr(head,-);
} void add(int u,int v,int c)
{
edge[tol]=Edge(v,c,head[u]);
head[u]=tol++;
} int SPFA(int n)
{
queue<int>q;
clr(cnt,);
rep(i,,n){
d[i]=;
inq[i]=true;
q.push(i);
}
inq[]=true;
while(!q.empty())
{
int u=q.front();q.pop();
inq[u]=false;
for(int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].v;
int c=edge[i].c;
if(d[v]<d[u]+c){
d[v]=d[u]+c;
if(!inq[v]){
q.push(v);
if(++cnt[v]>n)
return true;
inq[v]=true;
}
}
}
}
return false;
} int main()
{
int n,m;
int u,v,c;
char op[];
while(~scanf("%d",&n))
{
if(!n)
return ;
scanf("%d",&m);
init();
rep(i,,m){
scanf("%d%d%s%d",&u,&v,op,&c);
v+=u;u--;
if(op[]=='g')
add(u,v,c+);
else
add(v,u,-c+);
}
if(SPFA(n))
printf("successful conspiracy\n");
else
printf("lamentable kingdom\n");
}
return ;
}