POJ 1364(差分约束系统)

POJ 1364

(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;
}

猜你喜欢

转载自blog.csdn.net/qq_41829060/article/details/91614190