差分约束系统

僤鯓⒐⒋嵵緔 提交于 2019-11-27 03:12:22

差分约束

poj 3169 Layout
差分约束详解推荐 https://blog.csdn.net/whereisherofrom/article/details/78922648
Layout
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 17468 Accepted: 8409
Description

Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1…N standing along a straight line waiting for feed. The cows are standing in the same order as they are numbered, and since they can be rather pushy, it is possible that two or more cows can line up at exactly the same location (that is, if we think of each cow as being located at some coordinate on a number line, then it is possible for two or more cows to share the same coordinate).

Some cows like each other and want to be within a certain distance of each other in line. Some really dislike each other and want to be separated by at least a certain distance. A list of ML (1 <= ML <= 10,000) constraints describes which cows like each other and the maximum distance by which they may be separated; a subsequent list of MD constraints (1 <= MD <= 10,000) tells which cows dislike each other and the minimum distance by which they must be separated.

Your job is to compute, if possible, the maximum possible distance between cow 1 and cow N that satisfies the distance constraints.
Input

Line 1: Three space-separated integers: N, ML, and MD.

Lines 2…ML+1: Each line contains three space-separated positive integers: A, B, and D, with 1 <= A < B <= N. Cows A and B must be at most D (1 <= D <= 1,000,000) apart.

Lines ML+2…ML+MD+1: Each line contains three space-separated positive integers: A, B, and D, with 1 <= A < B <= N. Cows A and B must be at least D (1 <= D <= 1,000,000) apart.
Output

Line 1: A single integer. If no line-up is possible, output -1. If cows 1 and N can be arbitrarily far apart, output -2. Otherwise output the greatest possible distance between cows 1 and N.
Sample Input

4 2 1
1 3 10
2 4 20
2 3 3
Sample Output

27
Hint

Explanation of the sample:

There are 4 cows. Cows #1 and #3 must be no more than 10 units apart, cows #2 and #4 must be no more than 20 units apart, and cows #2 and #3 dislike each other and must be no fewer than 3 units apart.

The best layout, in terms of coordinates on a number line, is to put cow #1 at 0, cow #2 at 7, cow #3 at 10, and cow #4 at 27.
Source

USACO 2005 December Gold
汉语版

                                            布局
                          时间限制: 1000MS		内存限制: 65536K
描述

像其他人一样,奶牛喜欢在排队吃饭时站在他们的朋友附近。FJ有N(2 <= N <= 1,000)奶牛,编号为1..N,沿着直线等待饲料。奶牛的编号与它们编号的顺序相同,并且因为它们可能相当笨拙,所以有可能两头或多头母牛可以排列在完全相同的位置(也就是说,如果我们认为每头奶牛都位于在数字线上的某个坐标处,则两个或更多个奶牛可以共享相同的坐标。 

有些奶牛彼此喜欢,并希望在一定距离内排成一排。有些人真的不喜欢彼此,并希望至少分开一定的距离。ML(1 <= ML <= 10,000)约束的列表描述了彼此相似的奶牛以及它们可以分开的最大距离; 随后的MD约束列表(1 <= MD <= 10,000)告诉哪些奶牛彼此不喜欢以及它们必须分开的最小距离。 

如果可能,您的工作是计算满足距离约束的母牛1和母牛N之间的最大可能距离。
输入

第1行:三个以空格分隔的整数:N,ML和MD。 

第2行......ML + 1:每行包含三个以空格分隔的正整数:A,B和D,其中1 <= A <B <= N.奶牛A和B必须至多为D(1 <= D <= 1,000,000)分开。 

ML + 2..ML + MD + 1行:每行包含三个以空格分隔的正整数:A,B和D,其中1 <= A <B <= N.奶牛A和B必须至少为D( 1 <= D <= 1,000,000)。
产量

第1行:一个整数。如果没有可能的阵容,则输出-1。如果奶牛1和N可以任意相隔很远,则输出-2。否则输出奶牛1和N之间的最大距离。
样本输入

4 2 1
1 3 10
2 4 20
2 3 3
样本输出

27
暗示

样本说明: 

有4头奶牛。奶牛#1和#3必须相距不超过10个单位,奶牛#2和#4必须相隔不超过20个单位,而#2和#3奶牛彼此不相待,且必须相隔不少于3个单位。 

就数字线上的坐标而言,最佳布局是将牛#1置于0,将牛#2置于7,将牛#3置于10,将奶牛#4置于27。
资源

USACO 2005年12月黄金
#include <iostream>
#include <queue>
#include <cstdio>
#include <algorithm>
#include <cstring>
//#pragma GCC optimize(3 , "Ofast" , "inline")
using namespace std;
const int N = 1e6 + 10 ;
int e[N * 2] , ne[N * 2] , h[N * 2] , idx , w[N * 2] , dis[N] , vis[N] , n , out[N];
bool st[N] ;

void add(int a , int b , int c)
{
	e[idx] = b , w[idx] = c , ne[idx] = h[a] , h[a] = idx ++ ;
}
queue<int> q ;
void SPFA() // spfa模板
{
	for(int i = 0;i <= n;i ++) dis[i] = 0x3f3f3f3f ;
	q.push(1) ;
	memset(out , 0 , sizeof out) ;
	memset(st , false , sizeof st) ;
	dis[1] = 0 ; 
	st[1] = true ;
	int flag = 0 ;

	while(q.size())
	{
		int t = q.front() ;
		q.pop() ;
		st[t] = false ;
		out[t] ++ ;
		if(out[t] > n) 
	 {
	 	flag = 1 ;
	 	break ;
	 }
		for(int i = h[t] ;i != -1 ;i = ne[i])
		{
			int j = e[i] ;
			if(dis[j] > dis[t] + w[i])
			{
				dis[j] = dis[t] + w[i] ;
				if(!st[j])
				 {
				 	st[j] = true ;
				 	q.push(j) ;
				 }
			}
		}
	}
	if(flag)   // 这个判断时候是负环
	 printf("-1\n");
	else if(dis[n] == 0x3f3f3f3f) printf("-2\n");
	else printf("%d\n" , dis[n]); 
	
}
int main()
{
	int  n1 , n2 ;
	while(~scanf("%d%d%d",&n,&n1,&n2))
	{
		idx = 0 ;
	int a ,b , c ;
	for(int i = 0;i <= n;i ++) h[i] = -1 ;
	for(int i = 1;i <= n1 ;i ++)
	{
//	    s(b) - s(a) <= c    反向就是s(b) > c + s(a)  这个不就是spfa里面的松弛条件嘛 
 //    所以增加一条 边w(a , b) = c 
		scanf("%d%d%d",&a, &b, &c) ;   
		add(a , b , c) ;
	}
	for(int i = 1;i <= n2 ;i ++)
	{
	//同理  s(b) - s(a) >= c   同时乘以-1 得 s(a) - s(b) <= -c  这个又和上面那个一样了  
	//所以建立一条w(b , a , -c)  
		scanf("%d%d%d",&a , &b , &c) ;
		add(b , a , -c) ;
	}
	SPFA() ;
	}
	
	return  0;
} 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!