http://acm.hdu.edu.cn/showproblem.php?pid=2363
题目大意:
n个点,没个点都有不同的高度,同时n个点之间有m条路,题目要求从第1个点到第n个点,在所经过点的最高高度和最低高度的差最小的情况下的最短路径。
思路:
把每个点的高度升序排列,然后枚举各个高度差之间的最短路径,最后去高度差最小的最短路径,题目也就解决掉了,同时题目所给的点n最多只有100个,也不不会有超时的情况。
#include<algorithm>
#define inf 0x3fffffff
using namespace std;
int alti[101];
int n,m;
int dist[101],vis[101];
int map[101][101];
int sor[101];//¼Ç¼ËùÓеãµÄ¸ß¶È£¬ÅÅÐòºóÓÃÓÚö¾Ù
int Dijkstra(int Min,int Max) //DijkstraÇó×î¶Ì·¾¶
{
int i;
/*Initial*/
for(i=1;i<=n;i++)//³õʼ»¯
{
if(alti[i]>Max||alti[i]<Min)
vis[i]=1;//¸ß¶ÈÔÚÉÏϽçÍâµÄ£¬±ê¼ÇΪÒѾ×ß¹ý
else
{
dist[i]=map[1][i];
vis[i]=0;
}
}
dist[1]=0;
vis[1]=1;
while(1)
{
int Mina=inf,u=-1;
for(i=1;i<=n;i++)
{
if(alti[i]>Max||alti[i]<Min)
continue;
if(!vis[i]&&dist[i]<Mina)
{
Mina=dist[i];
u=i;
}
}
if(u==n)
return dist[u];
if(u==-1)
return -1;
vis[u]=1;
for(i=1;i<=n;i++)
{
if(alti[i]>Max||alti[i]<Min)
continue;
if(!vis[i]&&dist[u]+map[u][i]<dist[i])
dist[i]=dist[u]+map[u][i];
}
}
}
int main()
{
int i,j,t;
scanf("%d",&t);
int a,b,c;
while(t--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
map[i][j]=inf;
}
}
for(i=1;i<=n;i++)
{
scanf("%d",&alti[i]);
sor[i]=alti[i];
}
sort(sor+1,sor+n+1);//¸÷µã¸ß¶ÈÉýÐòÅÅÁÐ
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
if(c<map[a][b])
map[a][b]=map[b][a]=c;
}
int Min=inf,path;
for(i=1;i<=n;i++) //ö¾Ù¸÷¸ö¸ß¶È²î£¬Çó×î¶Ì·¾¶
{
for(j=i+1;j<=n;j++)
{
if(alti[n]>sor[j]||alti[n]<sor[i])//ÖÕµãÔڸ߶ȲΧÄÚ
continue;
if(alti[1]>sor[j]||alti[1]<sor[i])//ÆðµãÔڸ߶ȲΧÄÚ
continue;
if(sor[j]-sor[i]>Min)//ÓÉÓÚÌâÄ¿ÒªÇó£¬Ëù×ß·¾¶µÄ¸ß¶È²î×îС£¬ËùÒÔµ±¸ß¶È²î´óÓÚ֮ǰËùÇ󷾶ʱ£¬Ìø¹ý¡£
break;
/*DijkstraÇó³ö·¶Î§ÄÚ×î¶Ì·*/
int tmp=Dijkstra(sor[i],sor[j]);
if(tmp+1&&sor[j]-sor[i]==Min)//¸ß¶È²îÏàͬʱ£¬È¡×î¶Ì·
{
if(tmp<path)
path=tmp;
}
if(tmp+1&&sor[j]-sor[i]<Min)//¸ß¶È²î²»Í¬Ê±£¬È¡×îС¸ß¶È²î£¬¸üÐÂ×î¶Ì·
{
Min=sor[j]-sor[i];
path=tmp;
}
if(tmp!=-1)
break;
}
}
if(n==1)
printf("0 0\n");
else
printf("%d %d\n",Min,path);
}
}