大意:国王生了一个傻儿子,只会算从s开始的n个数的和大于或者小于k,他给你一组数据si、ni、ki,让你去判断是否存在这样的序列。
思路:建模,差分约束,然后判断是否存在环,并且需要判断图是否连通,而图不一定是连通的,所以我们增加一个超级源点n+1。然后最长路,最短路都行。
sn = s[i+1] +s[i+2]+....s[i+ni];
Tn = s1+s2+s3+s4+...sn;
sn = T[si+ni]-T[si-1] >=k+1;
sn = T[si+ni]-T[si-1] <=k-1;
差分约束只能求>=或者<=所以要转换为+1或者-1。
CODE:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int SIZE = 110;
const int INF = 0x3f3f3f3f;
int u[4*SIZE], v[4*SIZE], w[4*SIZE], next[4*SIZE];
int first[SIZE], d[SIZE];
int sum[SIZE];
int n, m, cnt;
void init()
{
memset(first, -1, sizeof(first));
memset(sum, 0, sizeof(sum));
cnt = 0;
}
int spfa(int src)
{
int stack[SIZE] = {0};
int ins[SIZE] = {0};
int top = 0;
for(int i = 0; i <= n+1; i++) d[i] = (i == src)?0:INF;
stack[top++] = src;
while(top)
{
int x = stack[--top];
ins[x] = 0;
for(int e = first[x]; e!=-1; e = next[e]) if(d[v[e]] > w[e]+d[x])
{
d[v[e]] = w[e] + d[x];
if(!ins[v[e]])
{
ins[v[e]] = 1;
if(++sum[v[e]] > n)
{
return 0;
}
stack[top++] = v[e];
}
}
}
return 1;
}
void read_graph(int u1, int v1, int w1)
{
u[cnt] = u1, v[cnt] = v1, w[cnt] = w1;
next[cnt] = first[u1];
first[u1] = cnt++;
}
int main()
{
int s;
while(~scanf("%d", &n), n)
{
init();
scanf("%d", &m);
while(m--)
{
char s[3];
int u1, v1, w1;
scanf("%d %d %s %d", &u1, &v1, s, &w1);
if(s[0] == 'g')
{
read_graph(u1+v1, u1-1, -w1-1);
}
else
{
read_graph(u1-1, u1+v1, w1-1);
}
}
s = n+1;
for(int i = 0; i <= n; i++) read_graph(s, i, 0);
int ans = spfa(s);
if(!ans)
{
printf("successful conspiracy\n");
}
else
{
printf("lamentable kingdom\n");
}
}
}
#include <cstdio>
#include <cstring>
using namespace std;
const int SIZE = 110;
const int INF = 0x3f3f3f3f;
int u[4*SIZE], v[4*SIZE], w[4*SIZE], next[4*SIZE];
int first[SIZE], d[SIZE];
int sum[SIZE];
int n, m, cnt;
void init()
{
memset(first, -1, sizeof(first));
memset(sum, 0, sizeof(sum));
cnt = 0;
}
int spfa(int src)
{
int stack[SIZE] = {0};
int ins[SIZE] = {0};
int top = 0;
for(int i = 0; i <= n+1; i++) d[i] = (i == src)?0:INF;
stack[top++] = src;
while(top)
{
int x = stack[--top];
ins[x] = 0;
for(int e = first[x]; e!=-1; e = next[e]) if(d[v[e]] > w[e]+d[x])
{
d[v[e]] = w[e] + d[x];
if(!ins[v[e]])
{
ins[v[e]] = 1;
if(++sum[v[e]] > n)
{
return 0;
}
stack[top++] = v[e];
}
}
}
return 1;
}
void read_graph(int u1, int v1, int w1)
{
u[cnt] = u1, v[cnt] = v1, w[cnt] = w1;
next[cnt] = first[u1];
first[u1] = cnt++;
}
int main()
{
int s;
while(~scanf("%d", &n), n)
{
init();
scanf("%d", &m);
while(m--)
{
char s[3];
int u1, v1, w1;
scanf("%d %d %s %d", &u1, &v1, s, &w1);
if(s[0] == 'g')
{
read_graph(u1+v1, u1-1, -w1-1);
}
else
{
read_graph(u1-1, u1+v1, w1-1);
}
}
s = n+1;
for(int i = 0; i <= n; i++) read_graph(s, i, 0);
int ans = spfa(s);
if(!ans)
{
printf("successful conspiracy\n");
}
else
{
printf("lamentable kingdom\n");
}
}
}