描述

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 ;
}

最新文章

  1. openlayer3 获取feature
  2. linux中的内存申请函数的区别 kmalloc, vmalloc
  3. Good Firewall(字典树 HDU4760)
  4. mac 下更新 .bash_profile 文件
  5. ZOJ1586——QS Network(最小生成树)
  6. MST最小生成树及克鲁斯卡尔(Kruskal)算法
  7. CentOS7 firewall的使用
  8. openStack云平台虚拟桌面galera mysql 3节点集群实例实战 调试完成
  9. C++高精度运算类bign (重载操作符)
  10. poj 3259 (Bellman_Ford判断负环)
  11. &lt;button&gt;与&lt;input type=&quot;button&quot;&gt;的区别
  12. 教你怎么样在大陆直接使用google搜索
  13. Java基础——Instanceof 运算符
  14. 关于 Socket 设置 setSoTimeout 误用的说明
  15. Subversion Edge部署
  16. Scrapy 框架 安装
  17. 基础 - 字符读取函数scanf、getchar、gets、cin(清空缓存区解决单字符回车问题)
  18. eclipse开发Java web工程时,jsp第一行报错,如何解决?
  19. oracle sum(x) over( partition by y ORDER BY z ) 分析
  20. String to Integer (atoi) leetcode java

热门文章

  1. 解决idea启动项目报错:Unable to open debugger port(127.0.0.1:60157):java.net.SocketException&quot;socket closed
  2. 上下两个div, 一个固定高度, 另一个铺满屏幕
  3. Hbase数据读写流程
  4. JavaScript:几种常用循环
  5. Spark、Hadoop、Hive相关文章
  6. Emac
  7. ANg-梯度下降算法
  8. week5 0.2 client
  9. FTP原理和虚拟用户映射登录-2019.2.8
  10. LinQ to sql简介及增删改查