zoj 1260 && poj 1364 King

题意:给定你一些不等式组,判定不等式组是否有解。


分析:对给出的不等式组建立差分约束系统,因为差分约束只能处理>= or <= 这样的不等式,所以我们首先要将不等式转化。若oi=gt,则s[u-1] - s[u+v] <= -k-1,若oi = lt,则s[u+v] - s[u-1] <= k-1,将这些条件都转化为边后,我们还需添加一个源点,将它与所有顶点添加一条权值为0的边,以便我们求单源最短路径。为了减少边的存储,spfa初始化时,将dist[i]赋值为0,并将所有顶点添加进入队列。


spfa代码

#include <iostream>
#include <cstdio>
#include <queue>

using namespace std;

const int inf = 100000000;
const int maxn = 105;


struct edge{
	int v,w;
	int next;
	
	edge(){};
};

int n,m;
int list[maxn];
int dist[maxn];
bool inq[maxn];
int cnt[maxn];
edge a[maxn];

void add_edge(int index, int u, int v, int w){
	a[index].v = v;
	a[index].w = w;
	a[index].next = list[u];
	list[u] = index;
}

bool input(){
	scanf("%d",&n);
	if(n == 0) return false;
	scanf("%d",&m);
	
	int u,v,w;
	char op[5];
	
	//clear
	for(int i = 0; i < maxn; i++) list[i] = -1;
	
	for(int i = 0; i < m; i++){
		scanf("%d%d%s%d",&u,&v,&op,&w);
		if(op[0] == 'g'){
			add_edge(i,u+v,u-1,-w-1);
		}
		else{
			add_edge(i,u-1,u+v,w-1);
		}
	}
	return true;
}


bool spfa(){
	queue<int> q;
	for(int i = 0; i <= n; i++){
		dist[i] = 0;//从源点走到所有点 
		q.push(i);
		inq[i] = true;
		cnt[i] = 1;
	}
	
	while(!q.empty()){
		int u = q.front(); q.pop(); inq[u] = false;
		
		for(int p = list[u]; p != -1; p = a[p].next){
			int v = a[p].v;
			int w = a[p].w;
			if(dist[u] + w < dist[v]){
				dist[v] = dist[u] + w;
				if(!inq[v]){
					q.push(v); inq[v] = true; cnt[v]++;
					if(cnt[v] > n) return false;
				}
			}
		}
	}
	return true;
}


int main(){
	while(input()){
		printf("%s\n",spfa()?"lamentable kingdom":"successful conspiracy");
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值