hdu3440--SPFA建图

来源:互联网 发布:多益网络实力 编辑:程序博客网 时间:2024/06/18 17:54

题意:
要从高度最低的地方st跳到高度最高的地方en 每次跳跃最大距离为d。也就是必须经过每一个点,且下一个位置要比当前位置高 。
每个位置都有一个高度值 并且顺序不能换 求st到en的最大距离。
比如说测试样例第一个跳的顺序为
3 -> 1 -> 2 -> 4
st到en的最大距离时的情况:
1 -③- 2 -①- 3 -③- 4
3和4之间最大距离是3

建图思路:两个位置之间最小距离是1, d[i+1] - d[i] >= 1 换成小于等于号 d[i] - d[i+1] <= -1, 所以 i+1 到 i 建一条-1的边。
然后对高度排序 相邻高度建边 ,从下标小的到下标大的建一条长度为d边 。因为我们要尽量让距离最大,所以相邻高度间建边就用最大长度。(差分约束的思想)

#include <iostream>#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<algorithm>using namespace std;const int inf=0x3f3f3f3f;const int maxn=1005;int head[maxn], egnum=0;struct Edge{    int next;    int to;    int w;};Edge edge[maxn*4];void addedge(int u,int v,int w){    edge[egnum].to = v;    edge[egnum].w = w;    edge[egnum].next = head[u];    head[u] = egnum++;}void init(){    memset(head,-1,sizeof(head));    egnum = 0;}bool vis[maxn];int cnt[maxn];int dist[maxn];bool spfa(int start,int n){    memset(vis,false,sizeof(vis));    memset(dist,0x3f,sizeof(dist));    memset(cnt,0,sizeof(cnt));    vis[start]=true;    dist[start]=0;    queue<int>que;    que.push(start);    cnt[start]=1;    while(!que.empty())    {        int u=que.front();        que.pop();        vis[u]=false;        for(int i=head[u]; i!=-1; i=edge[i].next)        {            int v=edge[i].to;            if(dist[v] > dist[u]+edge[i].w)            {                dist[v] = dist[u]+edge[i].w;                if(!vis[v])                {                    vis[v]=true;                    que.push(v);                    cnt[v]++;                    if(cnt[v]>=n)                        return false;                }            }        }    }    return true;}struct node{    int val,pos;} nt[maxn];bool cmp(node a,node b){    return a.val<b.val;}int main(){    int t,n,d;    scanf("%d",&t);    for(int cas=1; cas<=t; cas++)    {        scanf("%d%d",&n,&d);        for(int i=1; i<=n; i++)        {            scanf("%d",&nt[i].val);            nt[i].pos=i;        }        sort(nt+1,nt+1+n,cmp);        init();        for(int i=1; i<n; i++)        {            addedge(i+1,i,-1);            if(nt[i].pos<nt[i+1].pos)                addedge(nt[i].pos,nt[i+1].pos,d);            else                addedge(nt[i+1].pos,nt[i].pos,d);        }        printf("Case %d: ",cas);        int minn,maxn;        if(nt[1].pos<nt[n].pos)            minn=nt[1].pos,maxn=nt[n].pos;        else            minn=nt[n].pos,maxn=nt[1].pos;        if(!spfa(minn,n))            printf("-1\n");        else            printf("%d\n",dist[maxn]);    }    return 0;}
原创粉丝点击