Layout Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6549 Accepted: 3168
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
解題思路:
1、構造差分約束系統:
A,B距離不超過D則B-A<=D,
A,B距離至少為D則A-B<=-D.
2、若有解則求1和N之間的最短路徑:
例如:A-B<=D1 , B-C<=D2, A-C<=D3 不等式相加得:A-C<=min(D3,D1+D2)。而當A-B<=D時,我們建的邊是B->A的,所以我們只要求出1到N的最短距離即可,如果沒有最短距離,則輸出-2.
#include#include #include using namespace std; const int maxne = 1000000; const int maxnn = 1010; const int INF = 0x3f3f3f3f; struct edge{ int u , v , d; edge(int a = 0 , int b = 0 , int c = 0){ u = a , v = b , d = c; } }e[maxne]; int head[maxnn] , next[maxne] , cnt , dis[maxnn] , vis[maxnn] , vt[maxnn]; int N , ML , MD; void add(int u , int v , int d){ e[cnt] = edge(u , v , d); next[cnt] = head[u]; head[u] = cnt++; } void initial(){ for(int i = 0; i < maxnn; i++) head[i] = -1 , dis[i] = INF , vis[i] = 0 , vt[i] = 0; for(int i = 0; i < maxne; i++) next[i] = -1; cnt = 0; for(int i = 1; i < N; i++){ add(0 , i , 0); add(i+1 , i , 0); } add(0 , N , 0); dis[0] = 0; } void readcase(){ int u , v , d; while(ML--){ scanf("%d%d%d" , &u , &v , &d); add(u , v , d); } while(MD--){ scanf("%d%d%d" , &u , &v , &d); add(v , u , -1*d); } } bool SPFA(int start){ queue q; q.push(start); vt[start]++; while(!q.empty()){ int u = q.front(); q.pop(); vis[u] = 0; int n = head[u]; if(vt[u] > N+1){ return false; } while(n != -1){ int v = e[n].v; if(dis[v] > dis[u]+e[n].d){ dis[v] = dis[u]+e[n].d; if(vis[v] == 0){ vt[v]++; q.push(v); vis[v] = 1; } } n = next[n]; } } return true; } void computing(){ if(!SPFA(0)){ printf("-1\n"); }else{ for(int i = 0; i < maxnn; i++) dis[i] = INF; dis[1] = 0; SPFA(1); if(dis[N] == INF){ printf("-2\n"); }else{ printf("%d\n" , dis[N]); } } } int main(){ while(scanf("%d%d%d" , &N , &ML , &MD) != EOF){ initial(); readcase(); computing(); } return 0; }