题意是有N头牛,其中有ML对是相互喜欢的,它们之间不能超过一个距离,有MD对是互相不喜欢
的,它们的距离不得少于D。在ML中a, b, c分别代表两头牛的编号和最大距离,有a,b中max – min <= c。
而在MD中则反过来 min - max <= -c.即max <= min + c, min <= max - c.根据这个条件建图,然后求出第
一头牛到第n头牛的距离,如果存在,输出这个距离,如果存在负圈,输出-1,不存在答案输出-2.
/*Accepted 280K 47MS C++ 1803B 2012-08-06 14:53:35*/ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<queue> #define swap(t, a, b) (t = a, a = b, b = t); using namespace std; const int MAXN = 1 << 10, MAXM = 20020; const int inf = 0x3f3f3f3f; int n, ml, md, e, dist[MAXN], inq[MAXN], cnt[MAXN]; int first[MAXN], next[MAXM], v[MAXM], w[MAXM]; int relax(int u, int v, int w) { if(dist[v] > dist[u] + w) { dist[v] = dist[u] + w; return 1; } return 0; } void addedge(int a, int b, int c) { v[e] = b, w[e] = c; next[e] = first[a], first[a] = e ++; } void ReadGraph() { int a, b, c, t; memset(first, -1, sizeof first); e = 0; while(ml --) { scanf("%d%d%d", &a, &b, &c); if(a > b) swap(t, a, b); addedge(a, b, c); //b <= a + c } while(md --) { scanf("%d%d%d", &a, &b, &c); if(b > a) swap(t, a, b); addedge(a, b, -c); //b <= a - c } } int SPFA(int src, int n) { int i, u; queue<int> q; for(i = 1; i <= n; i ++) dist[i] = inf; memset(inq, 0, sizeof inq); memset(cnt, 0, sizeof cnt); dist[src] = 0; q.push(src); ++ cnt[src], inq[src] = 1; while(!q.empty()) { u = q.front(), q.pop(); inq[u] = 0; for(i = first[u]; i != -1; i = next[i]) { if(relax(u, v[i], w[i]) && !inq[v[i]]) { q.push(v[i]); inq[v[i]] = 1; if((++ cnt[v[i]]) > n) return -1; } } } if(inf == dist[n]) return -2; return dist[n]; } int main() { while(scanf("%d%d%d", &n, &ml, &md) == 3) { ReadGraph(); printf("%d\n", SPFA(1, n)); } return 0; }