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 }