spfa+差分约束系统(C

题目链接:https://cn.vjudge.net/contest/276233#problem/C

题目大意:有n层楼,给你每个楼的高度,和这个人单次的最大跳跃距离m,两个楼之间的距离最小是1,但是楼和楼之间的距离是能够调整的,现在有一个人,要从最矮的楼开始跳,每一次跳到比当前的楼高的楼上,然后问你在将所有的楼都走一遍的基础上,从第一个楼到最后一个楼之间的最远距离是多少?

思路:使用差分约束系统的相关知识, 我们可以建立如下不等式。

1,当相邻的时候,限制posA-posB>=1,也就是posB-posA<=-1。

2,当按照高度依次建立边的时候,我们就限制posA-posB<=m。这样的根据这两个式子就可以建立图了。

注意点:我们在建立相邻点的时候,是按照从小到大进行建边的,所以在对于第二种情况的时候,我们应该是先判断两个位置的大小,再去建边。

对差分约束系统的初步理解:如果是和spfa有关的话,具体就是建立不等式,然后如果求最大差值的话,我们直接将变建立成这两个点的最大差值就可以了。然后在跑最短路的过程中,就是找满足从posA到posB的所有不等式当中的最小的哪一个,因为求出来的值是要满足这两个点的所有不等式的。

AC代码:

  1 #include<iostream>
  2 #include<cstring>
  3 #include<stack>
  4 #include<iomanip>
  5 #include<cmath>
  6 #include<queue>
  7 #include<algorithm>
  8 #include<stdio.h>
  9 using namespace std;
 10 # define ll long long
 11 # define inf 1ll<<60
 12 const int maxn = 1000+100;
 13 const int maxedge= 1000000+10;
 14 int n;
 15 ll m;
 16 int num,head[maxn];
 17 ll dis[maxn];
 18 int out[maxn],vis[maxn];
 19 struct node
 20 {
 21     int fr;
 22     int to;
 23     ll cost;
 24     int nex;
 25 } edge[maxedge];
 26 struct point
 27 {
 28     int num;
 29     int id;
 30 } po[maxn];
 31 bool cmp(point t1,point t2)
 32 {
 33     return t1.num<t2.num;
 34 }
 35 void init()
 36 {
 37     for(int i=0; i<=n; i++)
 38     {
 39         head[i]=-1;
 40         out[i]=0;
 41         vis[i]=0;
 42         dis[i]=inf;
 43     }
 44     num=0;
 45 }
 46 void addedge(int fr,int to,ll cost)
 47 {
 48     edge[num].to=to;
 49     edge[num].cost=cost;
 50     edge[num].nex=head[fr];
 51     head[fr]=num++;
 52 }
 53 ll spfa(int st,int ed)
 54 {
 55     dis[st]=0;
 56     vis[st]=1;
 57     queue<int>q;
 58     q.push(st);
 59     while(!q.empty())
 60     {
 61         int tmp=q.front();
 62         q.pop();
 63         vis[tmp]=0;
 64         out[tmp]++;
 65         if(out[tmp]>n)
 66             return -1;
 67         for(int i=head[tmp]; i!=-1; i=edge[i].nex)
 68         {
 69             int u=edge[i].to;
 70             if(dis[u]>dis[tmp]+edge[i].cost)
 71             {
 72                 dis[u]=dis[tmp]+edge[i].cost;
 73                 if(vis[u])
 74                     continue;
 75                 vis[u]=1;
 76                 q.push(u);
 77             }
 78         }
 79     }
 80     return dis[ed];
 81 }
 82 int main()
 83 {
 84     int T;
 85     scanf("%d",&T);
 86     int Case=0;
 87     while(T--)
 88     {
 89         scanf("%d %lld",&n,&m);
 90         init();
 91         for(int i=1; i<=n; i++)
 92         {
 93             scanf("%d",&po[i].num);
 94             po[i].id=i;
 95         }
 96         for(int i=1; i<n; i++)
 97         {
 98             addedge(i+1,i,-1);
 99         }
100         sort(po+1,po+n+1,cmp);
101         for(int i=1; i<n; i++)
102         {
103             int u=po[i+1].id;
104             int v=po[i].id;
105             if(u>v)
106                 swap(u,v);
107             addedge(u,v,m);
108         }
109         int t1=po[1].id;
110         int t2=po[n].id;
111         if(t1>t2)
112             swap(t1,t2);
113         ll ans=spfa(t1,t2);
114         printf("Case %d: %lld
",++Case,ans);
115     }
116     return 0;
117 }
118  
原文地址:https://www.cnblogs.com/letlifestop/p/10262769.html