HDU - 3592 World Exhibition (差分约束)

题目链接

n个人按编号顺序站成一排,有两种约束:

1.A,B之间距离不超过c

2.A,B之间距离至少为c

差分约束模板题,注意最长距离模型要用最短路去解

对于第1类约束有d[B]-d[A]<=c,由A->B建立一条权值为c的边
对于第2类约束有d[B]-d[A]>=c,取反得d[A]-d[B]<=-c,由B->A建立一条权值为-c的边

此外,由于题目本身的限制,d[i+1]-d[i]>=0,由i+1向i建立一条零边

spfa跑最短路+判负环,如果有负环则无解,如果1不可达n则距离可为无穷大

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=1000+10,mod=1e9+7,inf=0x3f3f3f3f;
 5 int n,A,B,hd[N],ne,inq[N],vis[N],d[N];
 6 struct E {int v,c,nxt;} e[(int)1e5+10];
 7 void link(int u,int v,int c) {e[ne]= {v,c,hd[u]},hd[u]=ne++;}
 8 queue<int> q;
 9 bool upd(int u,int ad) {
10     if(d[u]>ad) {
11         d[u]=ad;
12         if(!inq[u]) {
13             q.push(u),inq[u]=1,vis[u]++;
14             if(vis[u]>n)return 0;
15         }
16     }
17     return 1;
18 }
19 int spfa() {
20     while(q.size())q.pop();
21     for(int i=1; i<=n; ++i)d[i]=inf,inq[i]=vis[i]=0;
22     upd(1,0);
23     while(q.size()) {
24         int u=q.front();
25         q.pop(),inq[u]=0;
26         for(int i=hd[u]; ~i; i=e[i].nxt) {
27             int v=e[i].v,c=e[i].c;
28             if(!upd(v,d[u]+c))return -1;
29         }
30     }
31     return d[n]==inf?-2:d[n];
32 }
33 int main() {
34     int T;
35     for(scanf("%d",&T); T--;) {
36         memset(hd,-1,sizeof hd),ne=0;
37         scanf("%d%d%d",&n,&A,&B);
38         for(int i=0; i<A; ++i) {
39             int u,v,c;
40             scanf("%d%d%d",&u,&v,&c);
41             link(u,v,c);
42         }
43         for(int i=0; i<B; ++i) {
44             int u,v,c;
45             scanf("%d%d%d",&u,&v,&c);
46             link(v,u,-c);
47         }
48         for(int i=1; i<n; ++i)link(i+1,i,0);
49         printf("%d\n",spfa());
50     }
51     return 0;
52 }

 

posted @ 2020-03-12 20:46  jrltx  阅读(168)  评论(0编辑  收藏  举报