(1)题意:
有一个序列长度为n,给出m次的约数,询问这m次限定能否确定一个序列。
输入n,m
然后m行,每行有四个参数si,ni,oi,ki
如果oi是gt就是>,否则是<.
如果最后能确定一个序列就输出“lamentable kingdom”,
否则输出“successful conspiracy”。
(2)思路:
如果是>,就是S[si+ni]-S[si-1]>k,
否则S[si+ni]-S[si-1]<k,S表示前缀和。
将它转化为最短路,
S[si-1]-S[si+ni]<=-z-1
S[si+ni] - S[si-1] <=z-1
然后再将所有点建立一个源点为n+1的图,判断是否存在负环就好了。
(3)代码:
(最短路求负环)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 105;
const int INF = 1e9+10;
int head[maxn],tot,vis[maxn],tim[maxn],dis[maxn],n,m,st[maxn<<2];
struct Node{
int v,nxt,w;
}cur[maxn<<2];
void Init(){
memset(head,-1,sizeof(head));
tot = 0;
}
void Add(int x,int y,int z){
cur[tot] = Node{y,head[x],z};
head[x] = tot++;
}
bool spfa(){
for(int i=0;i<=n+1;i++){
vis[i] = 0;dis[i] = INF;tim[i] = 0;
}
int top = 0;
st[top++] = n+1;dis[n+1] = 0;tim[n+1]++;
while(top!=0){
int x = st[--top];vis[x] = 0;
for(int i=head[x];i!=-1;i=cur[i].nxt){
int y = cur[i].v;
if(dis[y]>dis[x]+cur[i].w){
dis[y] = dis[x]+cur[i].w;
if(vis[y]==0){
vis[y] = 1;
if(++tim[y]>n+2) return false;
st[top++] = y;
}
}
}
}
return true;
}
int main(void){
while(~scanf("%d",&n)&&n){
scanf("%d",&m);
Init();
for(int i=0;i<m;i++){
char ss[10];
int x,y,z;scanf("%d%d%s%d",&x,&y,ss,&z);
if(ss[0]=='g') Add(x+y,x-1,-z-1);
else Add(x-1,x+y,z-1);
}
for(int i=0;i<=n;i++) Add(n+1,i,0);
if(spfa()==true) printf("lamentable kingdom\n");
else printf("successful conspiracy\n");
}
return 0;
}
(最长路求正环)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 105;
const int INF = 1e9+10;
int dis[maxn],vis[maxn],st[maxn<<2],head[maxn],tot,n,m,tim[maxn];
struct Node{
int v,nxt,w;
}cur[maxn<<2];
void Init(){
memset(head,-1,sizeof(head));
tot = 0;
}
void Add(int x,int y,int z){
cur[tot] = Node{y,head[x],z};
head[x] = tot++;
}
bool spfa(){
for(int i=0;i<=n+1;i++){
dis[i] = -INF;vis[i] = 0;tim[i] = 0;
}
int top = 0;
st[top++] = n+1;tim[n+1]++;dis[n+1] = 0;
while(top!=0){
int x = st[--top];vis[x] = 0;
for(int i=head[x];i!=-1;i=cur[i].nxt){
int y = cur[i].v;
if(dis[y]<dis[x]+cur[i].w){
dis[y] = dis[x]+cur[i].w;
if(vis[y]==0){
vis[y] = 1;
st[top++] = y;
if(++tim[y]>n+2) return false;
}
}
}
}
return true;
}
int main(void){
while(~scanf("%d",&n)&&n){
Init();
scanf("%d",&m);
for(int i=0;i<m;i++){
int x,y,z;char ss[10];
scanf("%d%d%s%d",&x,&y,ss,&z);
if(ss[0]=='g') Add(x-1,x+y,z+1);
else Add(x+y,x-1,-z+1);
}
for(int i=0;i<=n;i++){
Add(n+1,i,0);
}
if(spfa()==true) printf("lamentable kingdom\n");
else printf("successful conspiracy\n");
}
return 0;
}