这题目应该算是比较基础的差分约束吧,嘻嘻,也算是我的第一道差分约束,理解了题意之后,就是转化和构图的问题了
构图方法:
首先进行转换: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; }