UVALive 5532 King(差分约束,spfa)

题意:假设一个序列S有n个元素,现在有一堆约束,限制在某些连续子序列之和上,分别有符号>和<。问序列S是否存在?(看题意都看了半小时了!)

  注意所给的形式是(a,b,c,d),表示:区间之和:sum[a,a+b]<d或者sum[a,a+b]>d。而c是两个字符构成,判断前1个字符足矣。

思路:

  首先考虑要用点来表示什么,可以看到所给的是区间,也就是首尾的位置,可令sum(a)表示序列a[1...a]的和,那么表达式大概为sum(a+b)-sum(a-1)<k,由于小于号的存在,得换成小于等于号,所以表达式改为sum(a+b)-sum(a-1)<=k-1就行了。>号也是同理。所给的m个限制就被转换成边了。

  但是好像建完图后,里面有些块完全没联系啊(即不连通)?比如a[1...7]有个限制,a[4...9]也有个限制,但是这4个点压根就是两个帮派的!没有关系的哈,如果不是有交点的话,完全不会产生任何冲突的,比如sum(a[1...7])是与sum(a[4...9])没有任何联系的,因为他们的相交区间sum(a[4...7])的大小无论如何取值,只要在另外一部分另外取合适的值即可(可以为负数),不会冲突,比如sum(a[4....7])=10086,而sum(a[1...7])=0,则sum(a[1...3])=-10086即可。也可以这么说,子区间只要有一个数不同时被限制,无论如何都不会有冲突。

  再举例,a[1...7]和a[4...9]和a[1...9]这3个限制总算有联系了吧!自己画图吧,太难解释了。他们还是无法造成冲突。

 1 #include <bits/stdc++.h>
 2 #define INF 0x7f7f7f7f
 3 #define pii pair<int,int>
 4 #define LL unsigned long long
 5 using namespace std;
 6 const int N=150;
 7 struct node
 8 {
 9     int from, to, cost;
10     node(){};
11     node(int from,int to,int cost):from(from),to(to),cost(cost){};
12 }edge[N*N*2];
13 vector<int> vect[N];
14 int edge_cnt;
15
16 void add_node(int from,int to,int cost)
17 {
18     edge[edge_cnt]=node(from,to,cost);
19     vect[from].push_back(edge_cnt++);
20 }
21
22 set<int> sett;
23 int cost[N], cnt[N];
24 bool inq[N];
25 int spfa(int up)
26 {
27     memset(inq,  1, sizeof(inq));
28     memset(cnt,  0, sizeof(cnt));
29     memset(cost, 0, sizeof(cost));
30     deque<int> que;
31     for(set<int>::iterator it=sett.begin(); it!=sett.end(); it++)    que.push_back(*it);//全部进!
32
33     while(!que.empty())
34     {
35         int x=que.front();que.pop_front();
36         inq[x]=0;
37         for(int i=0; i<vect[x].size(); i++)
38         {
39             node e=edge[vect[x][i]];
40             if(cost[e.to]>cost[x]+e.cost)
41             {
42                 cost[e.to]=cost[x]+e.cost;
43                 if(!inq[e.to])
44                 {
45                     inq[e.to]=1;
46                     if(++cnt[e.to]>up)  return false;
47                     if(!que.empty()&&cost[e.to]<cost[que.front()])//优化
48                         que.push_front(e.to);
49                     else
50                         que.push_back(e.to);
51                 }
52             }
53         }
54     }
55     return true;
56 }
57
58 int main()
59 {
60     freopen("input.txt", "r", stdin);
61     int n, m, a, b, d, L, U;
62     char c[10];
63     while(scanf("%d", &n), n)
64     {
65         sett.clear();
66         edge_cnt=0;
67         memset(edge,0,sizeof(edge));
68         for(int i=0; i<=n; i++)  vect[i].clear();
69
70         scanf("%d",&m);
71         for(int i=0; i<m; i++)
72         {
73             scanf("%d %d %s %d ", &a, &b, &c, &d);
74             sett.insert(a-1);
75             sett.insert(a+b);
76             if(c[0]==‘g‘)   //大于
77             {
78                 add_node( a+b, a-1, -(d+1));
79             }
80             else
81             {
82                 add_node( a-1, a+b, d-1);
83             }
84         }
85         if(spfa(sett.size()))   puts("lamentable kingdom");
86         else    puts("successful conspiracy");
87     }
88     return 0;
89 }

AC代码

时间: 2024-10-09 16:31:40

UVALive 5532 King(差分约束,spfa)的相关文章

poj1364 King --- 差分约束

这是我见过最扯淡的题面之一. 题读了差不多一半我都觉得我这题肯定读不懂了,到最后终于看到重点了靠! 就是个差分约束大水题!毫无新意! 扯些什么皇后想生孩子!生了男孩是个弱智!父王很担心!这些有的没的有意思吗!! 题目就是给一个序列,告诉你 a b gt/lt c 表示从a起的b+1个数之和大于/小于c 就根据这个列不等式,要把> 或 <关系换成>= <= 就减一就可以了 列出不等式: S[a-1]-S[a+b]<=-c-1 S[a+b]-S[a-1]<=c-1 需要注意

POJ 3169 Layout (差分约束+SPFA)

Layout Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6832   Accepted: 3292 Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a

POJ 1364 King --差分约束第一题

题意:求给定的一组不等式是否有解,不等式要么是:SUM(Xi) (a<=i<=b) > k (1) 要么是 SUM(Xi) (a<=i<=b) < k (2) 分析:典型差分约束题,变换,令Ti = SUM(Xj) (0<=j<=i).  则表达式(1)可以看做T(a+b)-T(a-1) > k,也就是T(a-1)-T(a+b) < -k,又因为全是整数,所以T(a-1)-T(a+b) <= -k-1.  同理,(2)看做T(a+b)-T(

POJ 1364 King 差分约束 找负环

嘛,虽然是一道水题+模板题,不过还是学到了很多东西的,记录一下. 首先题目给出的不等式是小于,但是差分约束系统只能处理小于等于的情况,所以要转化成小于等于的进行处理.对于整数处理方法非常简单= = 然后是找负环的情况,其实不需要考虑图连不连通,只要一开始就把所有的点的d置成0,然后都push进队列里面就好了. PS:这种方法同样可以用在处理多源点最短路问题上. #include <cstdio> #include <cstring> #include <cmath> #

ZOJ 2770 Burn the Linked Camp 差分约束+SPFA

第一道正儿八经的差分约束题 有排成一列的n个点,首先告诉你每个点的值最多是多少(最少显然要大于0),然后告诉你m段i,j,k,表示第i个点到第j个点的值的和至少有k,问你总和至少为多少. 要注意的是,告诉你的所有关系式都不要忘记建边,一开始漏了大于0的条件调半天o(╯□╰)o 不等式的形式是a-b<=c这样的= = 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <

【bzoj2330】: [SCOI2011]糖果 图论-差分约束-SPFA

[bzoj2330]: [SCOI2011]糖果 恩..就是裸的差分约束.. x=1 -> (A,B,0) (B,A,0) x=2 -> (A,B,1)  [这个情况加个A==B无解的要特判] x=3 -> (B,A,0)  [恩这个是不少于一开始zz建反了] x=4 -> (B,A,1) x=5 -> (A,B,0) 然后源点到所有点建1的边[恩据说有条链所以要反着连]跑最长路就好了 1 /* http://www.cnblogs.com/karl07/ */ 2 #inc

UVALive 4885 Task 差分约束

题目链接:点击打开链接 题意: 有n个任务 m个限制条件 1.task i starts at least A minutes later than task j 表示 i - j >= A 2.task i starts within A minutes of the starting time of task j 表示 i - j <= A 问:每个任务开始的时间. 求一个任意解 思路: 差分约束,对于不等式形如: 点u,v : 常数C 有: u - v <= C 则从v->u

poj 1364 King(差分约束)(中等)

King Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11028   Accepted: 4040 Description Once, in one kingdom, there was a queen and that queen was expecting a baby. The queen prayed: ``If my child was a son and if only he was a sound kin

poj3159 差分约束 spfa

1 //Accepted 2692 KB 1282 ms 2 //差分约束 -->最短路 3 //TLE到死,加了输入挂,手写queue 4 #include <cstdio> 5 #include <cstring> 6 #include <iostream> 7 #include <queue> 8 #include <cmath> 9 #include <algorithm> 10 using namespace std;