POJ1364-King

知识点-差分约束

题目地址:POJ1364

例题

题目描述

  对于一个序列数字序列S。给出(si, ni, 0, ki)。

      如果是(si,ni,gt,ki),意思就是存在约束条件S[si]+S[si+1]+...S[si+ni] > ki,如果是(si,ni,lt,ki),意思就是存在约束条件S[si]+S[si+1]+...S[si+ni] < ki。

      判断所给的约束条件有无解,即是否存在这么一个序列S,有解就输出lamentable kingdom,无解就输出successful conspiracy。

输入

  含多组数据。

  每组数据第1行,两个整数,n,m,其中n代表序列s的长度,0<n<=100;m代表子序列的个数,0<m<=100。

  接下来m行,si,ni,o,ki,其中si,ni,ki为整数,o为gt代表大于,o为lt代表小于。

  最后一行为整数0,代表输入结束。

输出

  判断所给的约束条件有无解,即是否存在这么一个序列S,有解就输出lamentable kingdom,无解就输出successful conspiracy。

样例输入

4 2
1 2 gt 0
2 2 lt 2
1 2
1 0 gt 0
1 0 lt 0
0

样例输出

lamentable kingdom
successful conspiracy

分析

首先会发现本题目问约束条件下有无解,我们知道:如果一个图中含有负边权环,那么无解。所以问题就转移为问图是否含有负边权环。

根据题目已经给出的约束条件,我们发现都是a-b<k,a-b>k的形式,需要变换成a-b<=k-1,a-b>=k+1的形式。由于本题要找负边权环,那么肯定要找最短路,所以将a-b>=k+1的形式都转换为b-a<=-k-1。

两个约束条件:

a-b<=k-1

b-a<=-k-1

找负边权环的方法很简单:如果某个节点入队超过总的节点个数,那么说明有负边权环。

代码

 1 #include<iostream> 
 2 #include<cstring> 
 3 using namespace std; 
 4 string s; 
 5 int n,m,cnt,x,y,z,dis[1501],vis[1501],c[1501]; 
 6 int heads[1501],to[501],nxt[501],w[501],queue[10001]; 
 7 int addedge(int u,int v,int val) 
 8 { 
 9     w[++cnt]=val; 
10     to[cnt]=v; 
11     nxt[cnt]=heads[u]; 
12     heads[u]=cnt; 
13 } 
14 void spfa() 
15 { 
16     int head=0,tail=1; 
17     queue[1]=0;dis[0]=0;vis[0]=1; 
18     while(head<tail) 
19     { 
20         int u=queue[++head]; 
21         vis[u]=0; 
22         for(int i=heads[u];i;i=nxt[i]) 
23             if(dis[to[i]]>dis[u]+w[i]) 
24             { 
25                 dis[to[i]]=dis[u]+w[i]; 
26                 ++c[to[i]]; 
27                 if(c[to[i]]>n) 
28                 { 
29                     cout<<"successful conspiracy"<<endl; 
30                     return; 
31                 } 
32                 if(!vis[to[i]]) 
33                 { 
34                     queue[++tail]=to[i]; 
35                     vis[to[i]]=1; 
36                 } 
37             } 
38     } 
39     cout<<"lamentable kingdom"<<endl;return; 
40 } 
41 int main() 
42 { 
43     cin>>n; 
44     while (n) 
45     { 
46         cin>>m;cnt=0; 
47         memset(dis,0x7f,sizeof(dis)); 
48         memset(heads,0,sizeof(heads)); 
49         memset(vis,0,sizeof(vis)); 
50         memset(c,0,sizeof(c)); 
51         memset(queue,0,sizeof(queue)); 
52         for(int i=1;i<=m;++i) 
53         { 
54             cin>>x>>y>>s>>z; 
55             if(s=="lt")addedge(x,x+y+1,z-1); 
56             else addedge(x+y+1,x,-z-1); 
57         } 
58         for(int i=1;i<=n;++i) 
59             addedge(0,i,0); 
60         spfa(); 
61         cin>>n; 
62     } 
63 }  

posted on 2017-04-19 13:24  Skype_lorenzo  阅读(209)  评论(0编辑  收藏  举报

导航