这题目应该算是比较基础的差分约束吧,嘻嘻,也算是我的第一道差分约束,理解了题意之后,就是转化和构图的问题了
构图方法:
首先进行转换:a[j]+...+a[j+m] = a[1]+...a[j+m] - (a[1]+...+a[j-1]) = sum[j+m] -
sum[j-1]
>(<) ki. 差分约束只能全部是<=或者(>=).
第二步转换: sum[j+m]-sum[j-1] <= ki-1 或者
sum[j-1]-sum[j+m] <= -ki-1.
约束图构造好后就是简单的Bellman-Ford了!
注意,用bellman-Ford一定<= 或者>=,而题目给的只有< 或者> ,所以为了能用Bellman-Ford解决,就得在权重上面动手脚了,如上所示。
#include<iostream>
#include<string>
#include<queue>
#define MAXINT 9999999
#define MAXN 110
using namespace std;
int dis[MAXN],n,m,min1,max1;
struct edge
{
int u,v,w;
}e[MAXN];
bool bellman_ford()
{
for(int i=min1;i<=max1;i++)
dis[i]=MAXINT;
dis[min1]=0;//这里可要也可不要,因为Bellman-Ford是对所有边进行操作的,即使没有源点也照样进行松弛操作
for(int i=1;i<=n;i++)
{
for(int j=0;j<m;j++)
{
if(dis[e[j].v]>dis[e[j].u]+e[j].w)
dis[e[j].v]=dis[e[j].u]+e[j].w;
}
}
for(int j=0;j<m;j++)
{
if(dis[e[j].v]>dis[e[j].u]+e[j].w)
return false;
}
return true;
}
int main()
{
char str[5];
int a,b,c;
while(cin>>n)
{
if(n==0) break;
cin>>m;
max1=0;min1=MAXN;
for(int i=0;i<m;i++)
{
cin>>a>>b>>str>>c;
max1=max(a+b+1,max1);
min1=min(a,min1);
min1=min(b,min1);
if(strcmp(str,"gt")==0)
{
e[i].u=a+b+1;
e[i].v=a;
e[i].w=-c-1;
}
else {
e[i].v=a+b+1;
e[i].u=a;
e[i].w=c-1;
}
}
if(bellman_ford())
cout<<"lamentable kingdom"<<endl;
else cout<<"successful conspiracy"<<endl;
}
return 0;
}