Time Limit: 1000MS
Memory Limit: 65536K
Total Submissions: 8975
Accepted: 4308
Description
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).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 1 3 10 2 4 20 2 3 3
Sample Output
27
Hint
Explanation of the sample:
題意:有N頭牛,編號1~N。按照編號順序排成一排。在他們之間有些牛關系比較好,所以希望彼此之間不超過一定距離,給出ML表示有ML對(A,B,D),表示A與B間距離最大是D。也有一些牛關系非常不好,它們之間的距離也必須要大於一定距離。給出DL表示有DL對(A,B,D),表示A與B間距離最小是D。此外可能有多頭牛站在同一個位置。求1號牛到N號牛之間的距離。如果不存在任何一種滿足條件的排列方式則輸出-1。無限大的情況輸出-2。
題解:差分約束問題,轉化為最短路求解。設第i頭牛站在dis[i]的位置。要求牛按順序站立,我們可以知道dis[i+1]>=dis[i],從i+1到i的權值為0。根據給出的關系好的ML條信息,可以得到dis[MA]+MD>=dis[MB],這樣就從MA到MB的權值為MD(注意:是單向帶全圖)。根據給出的關系差的DL條信息,可以得到dis[DA]+DD<=dis[DB],這樣就從DB到DA的權值為DD。根據這三個約束條件(不等式),建圖。1號牛到N號牛的最長距離就是圖中的最短路徑。但圖中可能含有負權環,所以不能用dijsktra算法。SPFA算法能判斷負環。有負環的就表示不存在任何一種滿足條件的排列。
具體代碼如下:
#include#include #include #define maxn 1010 #define maxm 50010 #define INF 0x3f3f3f using namespace std; int dis[maxn],visit[maxn],mark[maxn],top,n; int head[maxn]; struct node { int to,val,next; }edge[maxm]; void add(int a,int b,int c) { edge[top].to=b; edge[top].val=c; edge[top].next=head[a]; head[a]=top++; } void spfa() { int i,v,u,mark[maxn]; queue q; for(i=1;i<=n;++i) { dis[i]=INF; visit[i]=0; mark[i]=0; } q.push(1); dis[1]=0; visit[1]=1; mark[1]=1;//記錄入隊列的次數 while(!q.empty()) { v=q.front(); q.pop(); visit[v]=0; for(i=head[v];i!=-1;i=edge[i].next) { u=edge[i].to; if(dis[u]>dis[v]+edge[i].val) { dis[u]=dis[v]+edge[i].val; if(!visit[u]) { visit[u]=1; mark[u]++; q.push(u); if(mark[u]>=n)//存在負環 { printf("-1\n"); return ; } } } } } if(dis[n]==INF)//表示最大距離可以無限大 printf("-2\n"); else printf("%d\n",dis[n]); } int main() { int ML,MD,u,v,d,i; while(scanf("%d%d%d",&n,&ML,&MD)!=EOF) { top=0; memset(head,-1,sizeof(head)); for(i=1;i