LOJ10090
题目描述
原题来自:USACO 2005 Dec. Gold
FJ 有 n 头奶牛(2<=n<=1000) ,编号为1..n 。奶牛们将按照编号顺序排成一列队伍(可能有多头奶牛在同一位置上)。换句话说,假设 i 号奶牛位于 p_i,则 p_1<=p_2<=...<=p_n。
有些奶牛是好基友,它们希望彼此之间的距离小于等于某个数。有些奶牛是情敌,它们希望彼此之间的距离大于等于某个数。
给出 m_l 对好基友的编号,以及它们希望彼此之间的距离小于等于多少;又给出 m_d 对情敌的编号,以及它们希望彼此之间的距离大于等于多少 (1<=m_l,m_d<=1e4)。
请计算:如果满足上述所有条件,1 号奶牛和 n 号奶牛之间的距离(p_n-p_1)最大为多少。
输入格式
第一行:三个整数 n,m_l,m_d,用空格分隔。
第 2...m_l+1 行:每行三个整数 a,b,d,用空格分隔,表示P_b-p_a<=d 。
第 m_l+2.. m_l+m_d+1 行:每行三个整数 a,b,d,用空格分隔,表示P_b-p_a>=d 。
保证 1<=a<=b<=n,1<=d<=1e6 。
输出格式
一行,一个整数。如果没有合法方案,输出 -1. 如果有合法方案,但 1 号奶牛可以与 n 号奶牛相距无穷远,输出-2 . 否则,输出 1 号奶牛与 n 号奶牛间的最大距离。
样例
______________________
差分约束
注意,1号店约束不到n好点,但是其余的点中间构成负环的情况!!!
如:
10 2 1 2 3 2 3 4 2 2 4 1012
______________________
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1010; 4 const int maxm=1e4+10; 5 int n,ml,md; 6 struct edge 7 { 8 int u,v,nxt; 9 long long w; 10 }e[maxm*4]; 11 int head[maxn],js; 12 void addage(int u,int v,long long w) 13 { 14 e[++js].u=u;e[js].v=v;e[js].w=w; 15 e[js].nxt=head[u];head[u]=js; 16 } 17 long long dis[maxn]; 18 bool inq[maxn]; 19 deque<int>q; 20 int cs[maxn]; 21 bool spfa() 22 { 23 memset(dis,0x3f,sizeof dis); 24 inq[0]=1;dis[0]=0; 25 q.push_back(0);++cs[0]; 26 while(!q.empty()) 27 { 28 int u=q.front();q.pop_front();inq[u]=0; 29 for(int i=head[u];i;i=e[i].nxt) 30 { 31 int v=e[i].v,w=e[i].w; 32 if(dis[v]>dis[u]+w) 33 { 34 dis[v]=dis[u]+w; 35 if(!inq[v]) 36 { 37 inq[v]=1;++cs[v]; 38 if(cs[v]>n)return 0; 39 if(!q.empty()&& dis[v]<=dis[q.front()])q.push_front(v); 40 else q.push_back(v); 41 } 42 } 43 } 44 } 45 return 1; 46 } 47 int main() 48 { 49 scanf("%d%d%d",&n,&ml,&md); 50 for(int i=1;i<n;++i)addage(i+1,i,0),addage(0,i,0x3f3f3f3f3f3f3f3f); 51 addage(0,1,0); 52 for(int a,b,d,i=1;i<=ml;++i) 53 { 54 scanf("%d%d%d",&a,&b,&d); 55 addage(a,b,d); 56 } 57 for(int a,b,d,i=1;i<=md;++i) 58 { 59 scanf("%d%d%d",&a,&b,&d); 60 addage(b,a,-d); 61 } 62 if(spfa()==0)puts("-1"); 63 else if(dis[n]==0x3f3f3f3f3f3f3f3f)puts("-2"); 64 else printf("%lld",dis[n]); 65 66 return 0; 67 }