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 }