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;}