标签:
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