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]; } } }
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。