hdu 6252 Subway Chasing (差分约束)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6252

 

题意:给出n个点,i-1到i的距离是不确定的,给出x代表两个人的距离,现在给出m条约束条件,每次给出A,B,C,D代表第一个人在区间(A,B)段,第二个人在区间(C,D)段,两个人的距离始终是x保持不变,求出一组每两个点距离都符合的可行解

数据范围:1≤T≤30,1≤N,M≤2000,1≤X≤1e9,1≤A,B,C,D≤N,A≤B≤A+1,C≤D≤C+1

 

差分约束算法:可以解决y-x<=常数的问题,那么对于y-x>=常数可以变成x-y<=-常数,对于y-x<常数可以变成y-x<=常数-1,对于y-x=常数可以变成y-x<=常数&&x-y<=常数,那么按照减数向被减数连一条权值为常数的边,再定义一个超级源点向每个点连一条权值为0的边跑spfa的最短路dis数组里储存的便是答案,所有的dis数组中的值都加一个常数就是另一组解

 

思路:对于m条约束每次,c-b<=x建边,d-a>=x建边,若是a==b&&c==d,那么就是c-a==x建边,然后因为每两个连续的点的距离大于等于1,所以a[i]-a[(i-1)]>=1建边,最后再建一个超级源点(我选的n)对所有点连一条权值为0的边跑spfa即可dis数组中的差值就是答案。

#include 
using namespace std;
const int N=5e4+5;
const int INF=0x7fffffff;
struct p{int to,val;};
vector

G[N]; int n,m,t,x,dis[N],cnt[N]; bool vis[N]; void spfa(){ memset(vis,0,sizeof(vis)); memset(cnt,0,sizeof(cnt)); for(int i=0;iQ; while(!Q.empty())Q.pop(); Q.push(n); bool flag=1; while(!Q.empty()){ int u=Q.front(); Q.pop(); vis[u]=0; for(int i=0;idis[u]+G[u][i].val){ dis[to]=dis[u]+G[u][i].val; if(!vis[to]){ vis[to]=1; Q.push(to); if(++cnt[to]>n){flag=0;break;} } } } if(flag==0)break; } if(flag==0)printf(" IMPOSSIBLE\n"); else{ for(int i=1;i

 

你可能感兴趣的:(acm算法学习)