Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10278 | Accepted: 4946 |
Description
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
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
Sample Input
4 2 1
1 3 10
2 4 20
2 3 3
Sample Output
27
Hint
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
题目大意:
一共有n头牛,有ml个关系好的牛的信息,有md个关系不好的牛的信息,对应输入的第一行的三个元素,接下来ml行,每行三个元素A,B,D,表示A牛和B牛相距不希望超过D,接下来md行,每行三个元素A,B,D表示A牛和B牛的相距至少要有D才行。求1号牛和n号牛的最大距离,如果距离无限大输出-2,如果无解输出-1。
思路:
1、因为我们要求1号牛和n号牛的最大距离,那么我们希望得到这样一个不等式(假设n==5):①-⑤<=x,那么这个x就是1号牛和n号牛的最大距离。
2、那么我们引入一个差分约束系统的相关概念:
差分约束系统问题,能够将问题转化为最短路问题。以下给出转化过程:
假设有这样的三个条件:
那么我们可以将不等式1和不等式2相加得到:
那么如果想要得到x1和x3的最大差值,那么其实就是取min(k1+k2,k3);
其实问题我们可以将问题转化成图论,将x1,x2,x3看成三个点x1,x2,x3,对应三条边的建立就根据三个不等式来建立,那么边权值如何取呢?显然我们想要最大差值,我们就需要取最大值,那么图可以建立成这样:
那么我们上述过程将不等式1和不等式2相加,然后和不等式3比较值的过程,其实就是最短路计算过程中的判断能否松弛的过程。
那么我们就可以根据不等式建立有向图,然后再通过有向图计算1号点到n号点的最短路,其值就是x1与xn的最大差值。
3、然后我们再回归到这个问题上来。
对应ml条信息:
①牛A和牛B的距离不想超过D,那么建立不等式:posA-posB<=D;加入到图中直接add(A,B,D)即可、
对应md条信息:
②牛A和牛B的距离至少要为D,那么建立不等式:posA-posB>=D,那么我们左右两边同乘-1有:posB-posA<=-D,那么加入到图中add(B,A,-D)即可。
4、图建立好之后直接跑最短路即可。
对应输出:
①如果dis【n】==inf,输出-2;
②否则输出dis【n】;
③如果在跑SPFA过程中发现了负环,说明问题无解,那么输出-1.
Ac代码:
-
#include<stdio.h>
-
#include<string.h>
-
#include<queue>
-
using
namespace
std;
-
struct node
-
{
-
int from;
-
int to;
-
int w;
-
int next;
-
}e[
200000];
-
int head[
10000];
-
int vis[
10000];
-
int out[
10000];
-
int dis[
10000];
-
int n,ml,dl,cont;
-
void add(int from,int to,int w)
-
{
-
e[cont].to=to;
-
e[cont].w=w;
-
e[cont].next=head[from];
-
head[from]=cont++;
-
}
-
void SPFA()
-
{
-
for(
int i=
1;i<=n;i++)dis[i]=
0x3f3f3f3f;
-
dis[
1]=
0;
-
memset(vis,
0,
sizeof(vis));
-
memset(out,
0,
sizeof(out));
-
queue<
int >s;
-
s.push(
1);
-
int flag=
0;
-
while(!s.empty())
-
{
-
int u=s.front();
-
out[u]++;
-
if(out[u]>n)
-
{
-
flag=
1;
-
break;
-
}
-
s.pop();
-
vis[u]=
0;
-
for(
int i=head[u];i!=
-1;i=e[i].next)
-
{
-
int v=e[i].to;
-
int w=e[i].w;
-
if(dis[v]>dis[u]+w)
-
{
-
dis[v]=dis[u]+w;
-
if(vis[v]==
0)
-
{
-
vis[v]=
1;
-
s.push(v);
-
}
-
}
-
}
-
}
-
if(flag==
1)
-
{
-
printf(
"-1\n");
-
}
-
else
if(dis[n]==
0x3f3f3f3f)
printf(
"-2\n");
-
else
printf(
"%d\n",dis[n]);
-
}
-
int main()
-
{
-
while(~
scanf(
"%d%d%d",&n,&ml,&dl))
-
{
-
cont=
0;
-
memset(head,
-1,
sizeof(head));
-
for(
int i=
0;i<ml;i++)
-
{
-
int x,y,w;
-
scanf(
"%d%d%d",&x,&y,&w);
-
add(x,y,w);
-
}
-
for(
int i=
0;i<dl;i++)
-
{
-
int x,y,w;
-
scanf(
"%d%d%d",&x,&y,&w);
-
add(y,x,-w);
-
}
-
SPFA();
-
}
-
}