原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2363
分析:最短路+二分。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<string> 7 #include<queue> 8 #include<vector> 9 #define ll long long 10 #define maxn 105 11 #define inf 0x7fffffff 12 using namespace std; 13 int T,n,m,low,up; 14 int h[maxn],map[maxn][maxn],h1[maxn]; 15 int d[maxn]; 16 bool vis[maxn]; 17 struct edge 18 { 19 int to,len; 20 edge(int x,int y) 21 { 22 to=x;len=y; 23 } 24 }; 25 vector<edge>e[maxn]; 26 queue<int>q; 27 void spfa(const int s) 28 { 29 while(!q.empty())q.pop(); 30 for(int i=1;i<=n;i++) 31 { 32 d[i]=inf;vis[i]=false; 33 } 34 d[s]=0;vis[s]=true; 35 if(h[s]<low||h[s]>up)return; 36 q.push(s); 37 while(!q.empty()) 38 { 39 int u=q.front();q.pop(); 40 for(int i=0;i<e[u].size();i++) 41 { 42 if(h[e[u][i].to]>=low&&h[e[u][i].to]<=up) 43 { 44 int tmp=d[u]+e[u][i].len; 45 if(d[e[u][i].to]>tmp) 46 { 47 d[e[u][i].to]=tmp; 48 if(!vis[e[u][i].to]) 49 { 50 vis[e[u][i].to]=true; 51 q.push(e[u][i].to); 52 } 53 } 54 } 55 } 56 vis[u]=false; 57 } 58 } 59 int main() 60 { 61 scanf("%d",&T); 62 while(T--) 63 { 64 for(int i=1;i<maxn;i++)e[i].clear(); 65 scanf("%d%d",&n,&m); 66 for(int i=1;i<=n;i++) 67 { 68 scanf("%d",&h[i]); 69 h1[i]=h[i]; 70 } 71 sort(h1+1,h1+n+1); 72 int u,v,len; 73 for(int i=1;i<=m;i++) 74 { 75 scanf("%d%d%d",&u,&v,&len); 76 e[u].push_back(edge(v,len)); 77 e[v].push_back(edge(u,len)); 78 } 79 int dif=inf,ans,minlen=inf; 80 int l=0,r=h1[n]-h1[1]; 81 while(l<=r) 82 { 83 int mid=(l+r)>>1; 84 bool flag=false; 85 for(int i=1;i<=n;i++) 86 { 87 low=h1[i]; 88 up=low+mid; 89 spfa(1); 90 if(d[n]!=inf) 91 { 92 flag=true; 93 ans=d[n]; 94 break; 95 } 96 } 97 if(flag) 98 { 99 r=mid-1; 100 if(dif>mid) 101 { 102 dif=mid; 103 minlen=ans; 104 } 105 else if(dif==mid&&ans<minlen) 106 minlen=ans; 107 } 108 else l=mid+1; 109 } 110 printf("%d %d ",dif,minlen); 111 } 112 return 0; 113 }