【基础练习】【差分】codevs1242 布局题解

题目描述 Description

当排队等候喂食时,奶牛喜欢和它们的朋友站得靠近些。FJN2<=N<=1000)头奶牛,编号从1N,沿一条直线站着等候喂食。奶牛排在队伍中的顺序和它们的编号是相同的。因为奶牛相当苗条,所以可能有两头或者更多奶牛站在同一位置上。即使说,如果我们想象奶牛是站在一条数轴上的话,允许有两头或更多奶牛拥有相同的横坐标。

一些奶牛相互间存有好感,它们希望两者之间的距离不超过一个给定的数L。另一方面,一些奶牛相互间非常反感,它们希望两者间的距离不小于一个给定的数D。给出ML条关于两头奶牛间有好感的描述,再给出MD条关于两头奶牛间存有反感的描述。(1<=ML,MD<=100001<=L,D<=1000000

你的工作是:如果不存在满足要求的方案,输出-1;如果1号奶牛和N

奶牛间的距离可以任意大,输出-2;否则,计算出在满足所有要求的情况下,1号奶牛和N号奶牛间可能的最大距离。

输入描述 Input Description
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 Description
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

如果A与B之间最多相距x 且B>A 即B-A>=x  那么B>=A+x 因此从A向B连一条距离为x的边 跑最短路 因为如果最多走x一定能走到 要求符合要求的最长距离就是x 因此最长允许距离中的最短路就是合法的最长距离 

最少相距同理 注意 要让符号一致  因此从B向A连一条-x的边

跑SPFA即可 因为最短路 如果出现负环无解 如果n点的值是无限大 可以是任意解


//codevs1242 布局 差分
//copyright by ametake
#include
#include
#include
#include
using namespace std;

const int maxn=1000+10;
const int maxm=20000+10;
int hd[maxn],t[maxm],nxt[maxm],v[maxm],et=0;
int n,m,k;
int dis[maxn],cnt[maxn];
bool inq[maxn],ok=false;;

queue q;

void add(int x,int y,int z)
{
	et++;
	t[et]=y;
	v[et]=z;
	nxt[et]=hd[x];
	hd[x]=et;
}

void spfa()
{
	memset(dis,0x3f,sizeof(dis));
	inq[1]=true;
	q.push(1);
	dis[1]=0;
	cnt[1]++;
	while (!q.empty())
	{
		int now=q.front();
		q.pop();
		inq[now]=0;
		for (int i=hd[now];i;i=nxt[i])
		{
			if (dis[now]+v[i]n)
					{
						ok=true;
						return;
					}
					inq[t[i]]=1;
				}
			}
		}
	}
}

int main()
{
	freopen("1.txt","r",stdin);
	scanf("%d%d%d",&n,&m,&k);
	int x,y,z;
	for (int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		if (x>y) swap(x,y);
		add(x,y,z);
	}
	for (int i=1;i<=k;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		if (x>y) swap(x,y);
		add(y,x,-z);
	}
	spfa();
	if (ok)
	{
		printf("-1\n");
		return 0;
	}
	if (dis[n]==0x3f3f3f3f) printf("-2\n");
	else printf("%d\n",dis[n]);
	return 0;
} 

马上博文就写完了 这件事也必须要说了


今天是2015年11月2日 是George Boole诞辰二百周年

这个人,大家看他的姓前四个字母就明白他是谁了。

他向我们展示出0和1所能舞动出的奇迹,他为我们打开位运算世界的大门,他用两个字节呈现出世界的无限可能,他将自己的生命奉献给了计算与数学教育事业。


【基础练习】【差分】codevs1242 布局题解_第1张图片


布尔先生,抬头看看上面那段代码吧,看看那个inq数组和ok变量,您会被千千万万的coder记住,您的功绩将伴随人类的历史一路前行。


——高山安可仰,徒此揖清芬。


你可能感兴趣的:(杂项基础练习,图论)