void-man

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

题目大意就是给出一串数,给出的约束是从第x到第x+y个数的和大于或者小小于val,问你这样的序列是否存在..

差分约束都是某两个数的差,但是这道题是某一区段的和问题,怎么解决?转换一下,由于题目没有让求和,可以用一个数组s[n]表示前n项的和

那么把n个点表示成前n项和来建图,至于大小关系需要转换,如果Ax+Ax+1+Ax+2+...Ax+y<K ==>S[x+y]-S[x-1]<K ==>S[x+y]-S[x-1]<=k-1.

可以说明x-1到x+y之间有一条权值k-1的边,同理Ax+Ax+1+Ax+2+...Ax+y>K ==>S[x+y]-S[x-1]>K==>S[x-1]-S[x+y]<=-1-K

可以得到x+y到x-1之间有一条-1-k权值的边

然后建图用bellman算法求解,松弛n次之后如果还可继续松弛那存在负环,无解,否则有解

 1 #include<string.h>
2 #include<stdio.h>
3 #include<stdlib.h>
4 #include<iostream>
5 #include<algorithm>
6 using namespace std;
7 int n,m,dis[110];
8 struct node
9 {
10 int x,y,val;
11 }N[10010];
12 void init()
13 {
14 memset(dis,0,sizeof(dis));//还不是太懂,为啥初始化成0,可能是刚上来没有数,每个位置到1的数和都是0吧
15
16 }
17 int bellman()
18 {
19 int x,y,val;
20 for(int i=0;i<n;i++)
21 {
22 for(int j=0;j<m;j++)
23 {
24 x=N[j].x;y=N[j].y;val=N[j].val;
25 if(dis[y]>dis[x]+val)
26 dis[y]=dis[x]+val;
27 }
28 }
29 for(int j=0;j<m;j++)//没有环就是不存在矛盾
30 {
31 x=N[j].x;y=N[j].y;val=N[j].val;
32 if(dis[y]>dis[x]+val)
33 return 0;
34 }
35 return 1;
36 }
37 int main()
38 {
39 int x,y,val;
40 char str[5];
41 while(scanf("%d",&n)!=EOF&&n)
42 {
43 scanf("%d",&m);
44 for(int i=0;i<m;i++)
45 {
46 scanf("%d%d%s%d",&x,&y,str,&val);
47 if(str[0]=='g')
48 {
49 N[i].x=x+y;
50 N[i].y=x-1;
51 N[i].val=-val-1;
52 }
53 else
54 {
55 N[i].y=x+y;
56 N[i].x=x-1;
57 N[i].val=val-1;
58 }
59 }
60 init();
61 printf("%s\n",bellman()?"lamentable kingdom":"successful conspiracy");
62 }
63 }

 

posted on 2011-08-26 00:40  void-man  阅读(200)  评论(0)    收藏  举报