hdu2363

来源:互联网 发布:mysql中删除列 编辑:程序博客网 时间:2024/05/18 03:50
/*
分析:
    枚举+Dij。
    给所有类点按高低排序,跟住类枚举上下限,给
这个限度内类点标记一下,然后用这些点进行Dij,就
中了。
    根据枚举方法不同,跳出枚举循环的判定也不同。


    反正我类方法系在第一次得到一个可行的情况后,
不能直接把它当做最后类答案,还得继续循环,不过
当前的上下限的△如果>已经得到的dir的话,那么这
种情况可以continue掉,也可以再进行一些修改让它
来个break,不过老麻烦了,影响也不大了,就不管了。


    234MS~


                                             2012-07-26
*/








#include"stdio.h"#include"math.h"#include"stdlib.h"#include"string.h"int n;struct A{int dis;int high;int flag;int hash;}E[111];int map[111][111];int cmp(const void *a,const void *b){return *(int *)a-*(int *)b;}int MIN(int a,int b){return a>b?b:a;}int DIJ(){int i,k;k=1;while(k){E[k].flag=0;for(i=1;i<=n;i++){if(k==i || !E[i].hash)continue;if(map[k][i]==1111111111)continue;if(E[k].dis+map[k][i]<E[i].dis)E[i].dis=E[k].dis+map[k][i];}k=0;for(i=1;i<=n;i++)if(E[i].flag && E[i].hash){k=i;break;}for(;i<=n;i++)if(E[i].flag && E[i].hash && E[i].dis<E[k].dis)k=i;}return E[n].dis;}int main(){int T;int m;int i,l,j;int temp[111];int a,b,c;int t,t1,t2;int ans,dir,len;scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);for(i=1;i<=n;i++){scanf("%d",&E[i].high);temp[i-1]=E[i].high;}qsort(temp,n,sizeof(temp[0]),cmp);for(i=1;i<=n;i++){for(l=1;l<=n;l++)map[i][l]=1111111111;map[i][i]=0;}while(m--){scanf("%d%d%d",&a,&b,&c);map[a][b]=map[b][a]=MIN(map[a][b],c);}t1=E[1].high;t2=E[n].high;if(t1>t2){t=t1;t1=t2;t2=t;}for(i=0;i<n;i++)if(temp[i]==t1){a=i;break;}for(i=n-1;i>=0;i--)if(temp[i]==t2){b=i;break;}dir=1111111111;len=1111111111;for(i=a;i>=0;i--){for(l=b;l<n;l++){if(abs(temp[i]-temp[l])>=dir)continue;for(j=1;j<=n;j++){E[j].dis=1111111111;E[j].flag=1;if(temp[i]<=E[j].high && E[j].high<=temp[l])E[j].hash=1;elseE[j].hash=0;}E[1].dis=0;len=DIJ();if(len!=1111111111){if(abs(temp[i]-temp[l])<dir){dir=abs(temp[i]-temp[l]);ans=len;}}}}printf("%d %d\n",dir,ans);}return 0;}