标签:
Input
Line 1: Three space-separated integers: N, ML, and MD.
Output
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
Sample Output
27
Hint
Explanation of the sample:
Source
USACO 2005 December Gold
题目大意:奶牛喜欢站成一排吃饲料,有的奶牛喜欢靠在一起,他们最多距离D米远。
有的奶牛不喜欢靠在一起,他们最少距离D米远才可以。给你一系列的约束条件,问:
如果在上述条件下,奶牛站不成一排,则输出"-1",如果能站成一排,但是第1头牛~
第N头牛的距离无限远,则输出"-2",如果满足条件,并且第1头牛~第N头牛之间存在
实际距离,则输出第1头牛~到第N头牛之间的能达到的最远距离。
思路:直接的差分约束系统,设牛u和牛v的位置为u和v。
第1条:设牛u和牛v最多距离w米远,转换为:v - u <= w。
第2条:设牛u和牛v最少距离w米远,转换为:u - v <= -w。
还有一个隐含条件:两头牛之间的距离最少为0米,转换为 i - (i+1) <= 0。遍历加入。
后来证明不加也可以A过。。。因为这个条件(-1 <= 0)本来就成立嘛
然后SPFA判断并求距离
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<queue> #define INF 0x7fffffff using namespace std; const int MAXN = 1100; const int MAXM = 30030; struct EdgeNode { int to; int w; int next; }Edges[MAXM]; int Head[MAXN],Dist[MAXN],vis[MAXN],outque[MAXN],id; void AddEdges(int u,int v,int w) { Edges[id].to = v; Edges[id].w = w; Edges[id].next = Head[u]; Head[u] = id++; } void SPFA(int s,int N) { int ans = 0; memset(vis,0,sizeof(vis)); memset(outque,0,sizeof(outque)); for(int i = 1; i <= N; ++i) Dist[i] = INF; Dist[s] = 0; vis[s] = 1; queue<int> Q; Q.push(s); while( !Q.empty() ) { int u = Q.front(); Q.pop(); vis[u] = 0; outque[u]++; if(outque[u] > N+1) { ans = -1; break; } for(int i = Head[u]; i != -1; i = Edges[i].next) { int temp = Dist[u] + Edges[i].w; if(temp < Dist[Edges[i].to]) { Dist[Edges[i].to] = temp; if( !vis[Edges[i].to]) { vis[Edges[i].to] = 1; Q.push(Edges[i].to); } } } } if(ans == -1) printf("-1\n"); else if(Dist[N] == INF) printf("-2\n"); else printf("%d\n",Dist[N]-Dist[1]); } int main() { int N,ML,MD,u,v,w; while(~scanf("%d%d%d", &N, &ML, &MD)) { memset(Head,-1,sizeof(Head)); id = 0; for(int i = 0; i < ML; ++i) { scanf("%d%d%d",&u,&v,&w); AddEdges(u,v,w); } for(int i = 0; i < MD; ++i) { scanf("%d%d%d",&u,&v,&w); AddEdges(v,u,-w); } //这里不加也可以 // for(int i = 1; i < N; ++i) // AddEdges(i+1,i,0); SPFA(1,N); } return 0; }
标签:
原文地址:http://blog.csdn.net/lianai911/article/details/43205435