POJ 1364 King (差分约束)

超级传送门

题目大意:

有一个序列S[1], S[2],S[3],S[4].....

读入si,ni,oi,ki,

oi表示大于和小于,如果是gt,则是大于,如果是lt,则是小于

输入表示 S[si]到S[si+ni]的和 大于/小于 ki

即:

T[si+ni]-T[si-1]>ki(oi为gt) 等价于:T[si-1]-T[si+ni]<-ki

T[si+ni]-T[si-1]<ki(oi为lt)

典型的差分约束,但是里面有一个小技巧,差分约束只能处理小于等于和大于等于的情况,在本题中,因为序列都是整数,可以转化为:

T[si-1]-T[si+ni]<-ki-1(oi为gt)

T[si+ni]-T[si-1]<=ki-1(oi为lt)


AC代码如下:

 

/*POJ1364
作者:陈佳润
2013-05-10*/
#include<iostream>
using namespace std;
#include<stdio.h>
struct Edge{
	int u,v;
	int w;
}edge[105];//存放边的结构体数组

int dis[105];//到源点距离表
int m;//边的数目
int n;//点的个数

void createEdge(int num,int u,int v,int w){
	edge[num].u=u;
	edge[num].v=v;
	edge[num].w=w;
}

bool Bellman(){
	int i,k;
	for(i=0;i<n;i++)//初始化
		dis[i]=0;
	//Bellman 算法
	for(i=0;i<n;i++){//Bellman 算法
		for(k=0;k<m;k++){
			if(dis[edge[k].v]>edge[k].w+dis[edge[k].u]){
				dis[edge[k].v]=edge[k].w+dis[edge[k].u];
			}
		}
	}
	//检查负权回路
	for(k=0;k<m;k++){
		if(dis[edge[k].v]>edge[k].w+dis[edge[k].u]){
			return false;
		}
	}
	return true;
}

int main(){
	char oi[3];
	int si,ni,ki,i;
	while(cin>>n,n){
		cin>>m;
		for(i=0;i<m;i++){//读入和建图
			scanf("%d%d%s%d",&si,&ni,oi,&ki);
			if(oi[0]=='g')
				createEdge(i,si+ni,si-1,-ki-1);
			else
				createEdge(i,si-1,si+ni,ki-1);	
		}
		
		if(!Bellman())
			printf("successful conspiracy\n");
        else
            printf("lamentable kingdom\n");
	}
	return 0;
}


 

 

posted @ 2013-05-10 20:20  坚固66  阅读(106)  评论(0编辑  收藏  举报