zoukankan      html  css  js  c++  java
  • hdu 3440 差分约束

    看完题目第一遍,感觉很简单。当写完程序跑测试用例的时候,发现第二个总是过不了,然后好好研究了一下测试用例,才知道原来不是程序有问题,而是我的建图方式错了。对于这些无序的点,如果高的在右边,不等式是dis[tall]-dis[short]<=d;如果高的在左边,那么不等式就要变成dis[short]-dis[tall]<=d了。

    另一个条件就是1<= dis[i+1]-dis[i] <=d;

    一定要选最高的和最低的两个点其中最靠左边的作为源点,那么求一次最短路的意义就是另一个点到它的最远距离。

    看代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define Maxn 1010
    #define inf 0x7fffffff
    #define Maxm Maxn*Maxn
    using namespace std;
    int dis[Maxn],index[Maxn],vi[Maxn],e,n;
    struct Edge{
        int to,next,val,from;
    }edge[Maxm];
    struct Point{
        int num,val;
    }p[Maxn];
    void init()
    {
        memset(vi,0,sizeof(vi));
        memset(index,-1,sizeof(index));
        e=0;
        for(int i=0;i<=n;i++)
        {
            dis[i]=inf;
        }
    }
    void addedge(int from, int to ,int val)
    {
        edge[e].to=to;
        edge[e].from=from;
        edge[e].val=val;
        edge[e].next=index[from];
        index[from]=e++;
    }
    int bellman_ford(int u)
    {
        int i,j,temp,flag;
        dis[u]=0;
        for(i=1;i<=n;i++)
        {
            flag=1;
            for(j=0;j<e;j++)
            {
                temp=edge[j].from;
                if(dis[temp]<inf&&dis[temp]+edge[j].val<dis[edge[j].to])
                {
                    dis[edge[j].to]=dis[temp]+edge[j].val;
                    flag=0;
                }
            }
            if(flag)
                return 1;
        }
        return 0;
    }
    int cmp(Point a,Point b)
    {
        return a.val<b.val;
    }
    int main()
    {
        int i,j,t,d,Case=0;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&d);
            init();
            for(i=1;i<=n;i++)
            {
                scanf("%d",&p[i].val);
                p[i].num=i;
            }
            for(i=1;i<n;i++)
            {
                addedge(i+1,i,-1);
                addedge(i,i+1,d);
            }
            sort(p+1,p+n+1,cmp);
            for(i=1;i<n;i++)
            {
                if(p[i].num>p[i+1].num)
                {
                    addedge(p[i+1].num,p[i].num,d);
                    addedge(p[i].num,p[i+1].num,-1);
                }
                else
                {
                    addedge(p[i].num,p[i+1].num,d);
                    addedge(p[i+1].num,p[i].num,-1);
                }
            
            }
            int u;
            if(p[1].num>p[n].num)
                u=p[n].num;
            else
                u=p[1].num;
            if(bellman_ford(u))
                printf("Case %d: %d
    ",++Case,abs(dis[p[n].num]-dis[p[1].num]));
            else
                printf("Case %d: -1
    ",++Case);
            //for(i=1;i<=n;i++)
                //cout<<dis[i]<<" ";
            //cout<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Lake Counting
    部分和问题
    迷宫最短路
    sublime 的使用技巧
    数组
    Factorial Trailing Zeroes
    Top K Frequent Elements
    Number of Connected Component in An Undirected Graph
    Zigzag Iterator
    Single Number III
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3200169.html
Copyright © 2011-2022 走看看