hdu2363 枚举+最短路

来源:互联网 发布:maka是什么软件 编辑:程序博客网 时间:2024/04/30 12:54
//思路:把每个点的高度升序排列,然后枚举各个高度差之间的最短路径,最后取高度差最小的最短路径.//注意数据的取值#include<iostream>#include<cstdio>#include<string.h>#include<algorithm>#define max 110#define maxint 0x4fffffffusing namespace std;int high[max];int tem[max];int dis[max];int vis[max];int map[max][max];int n,m;void init(){    int i,j;    for(i=1; i<max; i++)        for(j=1; j<max; j++)            map[i][j]=maxint;}int Dijkstra(int Min,int Max)//注意区间[Min,Max]{    int i,j;    for(i=1; i<=n; i++)    {        if(high[i]>Max||high[i]<Min)        {            vis[i]=0;            dis[i]=maxint;        }        else        {            vis[i]=0;            dis[i]=map[1][i];        }    }    vis[1]=1;    dis[1]=0;    while(1)    {        int mid=-1;        int d=maxint;        for(j=1; j<=n; j++)        {            if(high[j]>Max||high[j]<Min)                continue;            if(vis[j]==0&&dis[j]<d)            {                d=dis[j];                mid=j;            }        }        if(mid==n)            return dis[n];        if(mid==-1)            return -1;        vis[mid]=1;        for(j=1; j<=n; j++)        {            if(high[j]>Max||high[j]<Min)                continue;            if(vis[j]==0&&map[mid][j]+d<dis[j])                dis[j]=map[mid][j]+d;        }    }}int main(){    int t;    int a,b,c;    int Min,Max;    scanf("%d",&t);    while(t--)    {        init();        scanf("%d%d",&n,&m);        for(int i=1; i<=n; i++)        {            scanf("%d",&high[i]);            tem[i]=high[i];        }        sort(tem+1,tem+n+1);        for(int i=1; i<=m; i++)        {            scanf("%d%d%d",&a,&b,&c);            if(map[a][b]>c)                map[a][b]=map[b][a]=c;        }        //枚举所用情况        int min=maxint,path,ans;        for(int i=1; i<n; i++)            for(int j=i+1; j<=n; j++)            {                //判断起点和终点是不是都在这个区间内。                if(high[1]<tem[i]||high[1]>tem[j])                    continue;                if(high[n]<tem[i]||high[n]>tem[j])                    continue;                if(tem[j]-tem[i]>min)                   break;                ans=Dijkstra(tem[i],tem[j]);              //  printf("tem=%d  \n",ans);               if(ans+1&&tem[j]-tem[i]==min)//如果高度差相等               {                   if(path>ans)                     path=ans;               }               if(ans+1&&tem[j]-tem[i]<min)//如果高度差不等               {                   min=tem[j]-tem[i];                   path=ans;               }               if(ans!=-1)                 break;            }            if(n==1)            {                printf("0 0\n");            }            else             {                printf("%d %d\n",min,path);             }    }    return 0;}

原创粉丝点击