描述

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.

输入

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.

输出

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.

样例输入

4 2 1
1 3 10
2 4 20
2 3 3

样例输出

27

提示

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.

题意
有N头牛,按1-N排序,有ML对互相喜欢的牛,距离<=d,有MD对互相厌恶的牛,距离>=d,求牛1到牛N的最大距离,若不能按1-N排序(无解)输出-1,若1-N距离可以为无穷输出-2,其余输出1-N的距离
题解
这道题也是磨了很久才搞定的,对差分约束理解的不是很好
首先大致讲下差分约束
首先给你一堆式子
B-A<=c//1
C-B<=a//2
C-A<=d//3
求C-A的最大值
这里把1+2,得到C-A<=a+c//1
          C-A<=d    //2
这里可以看到,要同时满足1和2,就是max(C-A)=min(a+c,d)
我们看题目,通过题目可以写出下面几个不等式
Dist(J)-Dist(J-1)>=0(2<=j<=4) //1
Dist(3)-Dist(1)<=10                     //2
Dist(4)-Dist(2)<=20                     //3
Dist(3)-Dist(2)>=3          //4
这里把1和4做个变化,和23符号一致,得到
Dist(J-1)-Dist(J)<=0(2<=j<=4) //1
Dist(3)-Dist(1)<=10                     //2
Dist(4)-Dist(2)<=20                     //3

Dist(2)-Dist(3)<=-3         //4

对于满足像D[X]-D[Y]<=Z的情况,可以建立一条Y->X距离为Z的有向边,求1->N的最大值,就是求1->N的最短路径
如果满足像D[X]-D[Y]>=Z的情况,求1->N的最小值,就是求1->N的最长路径
 
解的存在性
差分约束存在3种情况
1.有解(直接输出Dist[n])
2.无解,出现负权圈,图内有两点之间有一个圈然后这个圈的权是负的,A-B和B-A的权都是负数(一个点的入队或者入栈次数>n就说明有负圈)(输出-1)
3.无穷多解,如果1到N根本不可达,就说明两者没有约束条件,可是是无穷多解(输出-2)
 
链式前向星
这里讲一下链式前向星存图
const int N=,M=;
int head[N],cnt=;
struct edge
{
int v,w,next;
}edges[M];
void add(int u,int v,int w)
{
edges[cnt].v=v;
edges[cnt].w=w;
edges[cnt].next=head[u];
head[u]=cnt++;
}

上面这个意思是每次在链表结构里的首部存一条(u,v)权值为w的边,这个存储和输入方式是成逆序的,而且时间O(1),空间没有浪费

所以只需要i=head[u];i!=0;i=edges[i].next就可以访问所有从U出发的边

然后这道题就是建图,建完图跑最短路径,这里用SPFA可以判断负圈

代码
这里SPFA用栈来做了,当然用队列也可以
 #include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
#define INF 0x3f3f3f3f
const int N=,M=;
struct edge
{
int v,w,next;
}edges[M];
int Dist[N],Vis[N],head[N],In[N],cnt=;
void add(int u,int v,int w)
{
edges[cnt].v=v;
edges[cnt].w=w;
edges[cnt].next=head[u];
head[u]=cnt++;
}
int spfa(int n)
{
memset(Dist,INF,sizeof(Dist));
stack<int> st;
st.push();
Dist[]=;
while(!st.empty())
{
int u=st.top();st.pop();
Vis[u]=;
for(int i=head[u];i;i=edges[i].next)
{
int v=edges[i].v,w=edges[i].w;
if(Dist[v]>Dist[u]+w)
{
Dist[v]=Dist[u]+w;
if(Vis[v])continue;
Vis[v]=;
st.push(v);
if(++In[v]>n)return ;//一个点的入栈次数>n说明存在负圈,无解
}
}
}
return ;
}
int main()
{
int n,ml,md,a,b,c;
scanf("%d%d%d",&n,&ml,&md);
for(int i=;i<ml;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
for(int i=;i<md;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(b,a,-c);//差分约束
}
if(spfa(n)==)printf("-1\n");
else printf("%d\n",Dist[n]==INF?-:Dist[n]);
return ;
}

POJ 3169 Layout(差分约束+链式前向星+SPFA)的更多相关文章

  1. [poj3159]Candies(差分约束+链式前向星dijkstra模板)

    题意:n个人,m个信息,每行的信息是3个数字,A,B,C,表示B比A多出来的糖果不超过C个,问你,n号人最多比1号人多几个糖果 解题关键:差分约束系统转化为最短路,B-A>=C,建有向边即可,与 ...

  2. 链式前向星+SPFA

    今天听说vector不开o2是数组时间复杂度常数的1.5倍,瞬间吓傻.然后就问好的图表达方式,然后看到了链式前向星.于是就写了一段链式前向星+SPFA的,和普通的vector+SPFA的对拍了下,速度 ...

  3. 【模板】链式前向星+spfa

    洛谷传送门--分糖果 博客--链式前向星 团队中一道题,数据很大,只能用链式前向星存储,spfa求单源最短路. 可做模板. #include <cstdio> #include <q ...

  4. POJ 3169 Layout (差分约束)

    题意:给定一些母牛,要求一个排列,有的母牛距离不能超过w,有的距离不能小于w,问你第一个和第n个最远距离是多少. 析:以前只是听说过个算法,从来没用过,差分约束. 对于第 i 个母牛和第 i+1 个, ...

  5. POJ 3169 Layout(差分约束啊)

    题目链接:http://poj.org/problem? id=3169 Description Like everyone else, cows like to stand close to the ...

  6. POJ 3169 Layout(差分约束 线性差分约束)

    题意: 有N头牛, 有以下关系: (1)A牛与B牛相距不能大于k (2)A牛与B牛相距不能小于k (3)第i+1头牛必须在第i头牛前面 给出若干对关系(1),(2) 求出第N头牛与第一头牛的最长可能距 ...

  7. poj 3169 Layout 差分约束模板题

    Layout Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6415   Accepted: 3098 Descriptio ...

  8. POJ 1511 Invitation Cards 链式前向星+spfa+反向建边

    Invitation Cards Time Limit: 8000MS   Memory Limit: 262144K Total Submissions: 27200   Accepted: 902 ...

  9. POJ 1511 链式前向星+SPFA

    #include<iostream> #include<cstdio> #include<cstdlib> using namespace std; const i ...

随机推荐

  1. 开源项目几点心得,Java架构必会几大技术点

    关于学习架构,必须会的几点技术 1. java反射技术     2. xml文件处理     3. properties属性文件处理     4. 线程安全机制     5. annocation注解 ...

  2. 代码直连指定ip的dubbo服务

    http://blog.csdn.net/buqutianya/article/details/69229384

  3. Bash:精华

    # 声明索引数组(以从0开始的整数做索引的数组).以下三种等效. declare -a array declare array=(this is numeric array ) array=(this ...

  4. Linux命令:chown

    Linux命令:chmod https://baijiahao.baidu.com/s?id=1616750933810368135&wfr=spider&for=pc chmod - ...

  5. How to Pronounce the 50 States

    How to Pronounce the 50 States (1/4) Share Tweet Share Tagged With: Places The US state names can be ...

  6. Python基本模块介绍:sys、platform

    sys模块 常用函数 sys.argv 命令行参数,实现从程序外部向程序传递参数. sys.path 模块搜索路径. sys.platform 获取当前系统平台. sys.version 获取pyth ...

  7. 360Top奢侈品演示站 - 纯手工纪念品

    一个纯手写的过程化编程商城项目,留作纪念. 360Top奢侈品演示站 http://360top.farwish.com

  8. nth-child与nth-of-type区别

    示例详细理解:nth-child(n)与:nth-of-type(n)区别 childselector:nth-child(index) 1,子选择器(childselector,这里是p选择器)选中 ...

  9. C++ 关于滚动条的滚动问题

    SCROLLINFO scrollinfo; GetScrollInfo(SB_HORZ, &scrollinfo, SIF_ALL); switch (nSBCode) { case SB_ ...

  10. C# 图像处理:获取鼠标位置信息(全局)

    Point ms = Control.MousePosition; //获取鼠标位置 this.label2.Text = string.Format("{0}:{1}", ms. ...