HDU--3592(差分约束)

2015-01-07 00:40:57

思路:差分约束题,用Si表示 i 距离第1个人的距离。根据条件:(1)约束一:S(b) - S(a) <= c (2)约束二:S(b) - S(a) >= c

  因为要求最长可能距离,所以转化为求最短路。约束一化为:S(b) <= S(a) + c,约束二化为:S(a) <= S(b) + (-c)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <iostream>
11 #include <algorithm>
12 using namespace std;
13 #define lp (p << 1)
14 #define rp (p << 1|1)
15 #define getmid(l,r) (l + (r - l) / 2)
16 #define MP(a,b) make_pair(a,b)
17 typedef long long ll;
18 typedef unsigned long long ull;
19 typedef pair<int,int> pii;
20 const int INF = (1 << 30) - 1;
21 const int maxn = 10010;
22 
23 int T,N,X,Y;
24 int first[maxn],ecnt;
25 int cnt[maxn],inq[maxn],dis[maxn];
26 
27 struct edge{
28     int v,next,cost;
29 }e[maxn << 1];
30 
31 void Add_edge(int u,int v,int c){
32     e[++ecnt].next = first[u];
33     e[ecnt].v = v;
34     e[ecnt].cost = c;
35     first[u] = ecnt;
36 }
37 
38 bool Spfa(int s){
39     queue<int> Q;
40     memset(inq,0,sizeof(inq));
41     memset(cnt,0,sizeof(cnt));
42     fill(dis + 1,dis + N + 1,INF);
43     dis[s] = 0;
44     inq[s] = cnt[s] = 1;
45     Q.push(s);
46     while(!Q.empty()){
47         int x = Q.front(); Q.pop();
48         inq[x] = 0;
49         //printf("x : %d\n",x);
50         for(int i = first[x]; i != -1; i = e[i].next){
51             int v = e[i].v;
52             //printf("v : %d\n",v);
53             if(dis[v] > dis[x] + e[i].cost){
54                 dis[v] = dis[x] + e[i].cost;
55                 if(inq[v] == 0){
56                     inq[v] = 1;
57                     cnt[v]++;
58                     if(cnt[v] > N)
59                         return false;
60                     Q.push(v);
61                 }
62             }
63         }
64     }
65     return true;
66 }
67 
68 int main(){
69     int a,b,c;
70     scanf("%d",&T);
71     while(T--){
72         //Init
73         memset(first,-1,sizeof(first));
74         ecnt = 0;
75         scanf("%d%d%d",&N,&X,&Y);
76         for(int i = 1; i <= X; ++i){
77             scanf("%d%d%d",&a,&b,&c);
78             //S(b) - S(a) <= c --> S(b) <= S(a) + c
79             Add_edge(a,b,c);
80         }
81         for(int i = 1; i <= Y; ++i){
82             scanf("%d%d%d",&a,&b,&c);
83             //S(b) - S(a) >= c --> S(a) - S(b) <= -c --> S(a) <= S(b) + (-c)
84             Add_edge(b,a,-c);
85         }
86         for(int i = 1; i <= N; ++i){
87             //S(i) - S(i - 1) >= 0 --> S(i - 1) <= S(i) + 0
88             Add_edge(i,i - 1,0);
89         }
90         if(Spfa(1) == false) printf("-1\n");
91         else if(dis[N] >= INF) printf("-2\n");
92         else printf("%d\n",dis[N]);
93     }
94     return 0;
95 }

 

posted @ 2015-01-07 00:45  Naturain  阅读(158)  评论(0编辑  收藏  举报