hdu2362(枚举+最短路)

http://acm.hdu.edu.cn/showproblem.php?pid=2363

题意:给你n点,m条路,每个点都有不同的高度,题目要求在高度差最小的情况下的最短路径。

开始做这个题目时,我是用二次最短路在做的,回来发现思路错了,就参考了大牛代码,恍然大悟。

只要对高度升序排序,然后枚举各个高度差下的最短路径

代码:

#include<iostream>
#include<algorithm>
using namespace std;
#define p 1500000001
int a[105],b[105],s[105][105],n;
int main()
{
    int dj(int max,int min);
    int i,j,m,t,x,y,z,min,h,temp;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                s[i][j]=p;
            for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        sort(a+1,a+n+1);
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            if(z<s[x][y])
                s[x][y]=s[y][x]=z;
        }
        h=min=p;
        for(i=1;i<=n;i++)
        {
            for(j=i+1;j<=n;j++)
            {
                if(a[i]>b[1]||b[1]>a[j])    //起点需要在高度差范围内
                    continue;
                if(a[i]>b[n]||b[n]>a[j])      //终点需要在高度差范围内
                    continue;
                if(a[j]-a[i]>h)           //判断高度差是否比前一次的高度差小
                    break;
                temp=dj(a[j],a[i]);
                if(a[j]-a[i]==h&&temp!=-1)   //在高度差相等的情况下,取最短的路径
                {
                    if(temp<min)
                        min=temp;
                }
                if(a[j]-a[i]<h&&temp!=-1)
                {
                    h=a[j]-a[i];
                    min=temp;
                }
                if(temp!=-1)        //如果找到了,则不需要再往下找
                    break;

            }
        }
        if(n==1)
            printf("0 0\n");
        else
        printf("%d %d\n",h,min);
    }
    return 0;
}
int dj(int max,int min)
{
    int i,k,vist[105],dist[105],minx;
    for(i=1;i<=n;i++)
        if(b[i]<min||b[i]>max)   //点需要在高度差范围内
        {
            vist[i]=0;
            dist[i]=p;
        }
        else
        {
            vist[i]=0;
            dist[i]=s[1][i];
        }
    vist[1]=1;
    dist[1]=0;
    while(1)
    {
        minx=p;
        k=-1;
        for(i=1;i<=n;i++)
        {
            if(b[i]<min||b[i]>max)     //点需要在高度差范围内
                continue;
            else
            {
                if(!vist[i]&&dist[i]<minx)
                {
                    minx=dist[i];
                    k=i;
                }
            }
        }
        if(k==-1)          
            return -1;
        if(k==n)
            return dist[k];
        vist[k]=1;
        for(i=1;i<=n;i++)
        {
            if(b[i]<min||b[i]>max)
                continue;
            else
                if(!vist[i]&&s[k][i]<p&&s[k][i]+dist[k]<dist[i])
                    dist[i]=s[k][i]+dist[k];
        }
    }
}

 

posted @ 2012-11-24 11:34  紫忆  阅读(200)  评论(0编辑  收藏  举报