http://acm.hdu.edu.cn/showproblem.php?pid=2363
思路:思路其实是和hdu1598类似,先对100个点进行排序,然后枚举最大高度最小高度, 时间复杂度为O(N^2),然后对于每个枚举的最高最低点,对100个点进行筛选,高度在这两者之间的点标记为合法点,然后就是对标记了的结点进行一个Dij, 复杂度为:O(N^2),可以用优先队列优化到O(N*logN),这样就可以求出从源点1到N 的最短路了。时间性能为:O(N^3*logN),N为100 ,1000+MS水过 。。。。。
代码:
/*
Dijkstra
*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
const int INF = 0x3f3f3f3f ;
struct Node{
int h ;
int num ;
}node[110] ;
int T ,N,M;
int map[110][110] ;
bool with[110];
bool comp(Node n1, Node n2){
return n1.h < n2.h ;
}
bool vis[110] ;
int dis[110] ;
int min_h , min_d ;
struct Node1{
Node1(int a, int b)
:d(a) , num(b) {}
int d ,num ;
friend bool operator <(const Node1& n1 , const Node1 &n2){
if(n1.d == n2.d) return n1.num < n2.num ;
return n1.d > n2.d ;
}
};
priority_queue<Node1> que ;
int Dij(){
while(!que.empty()) que.pop() ;
for(int i=2;i<=N;i++){
vis[i] = 0 ;
if(with[i] == 0) continue ;
que.push( Node1( map[1][i] , i)) ;
dis[i] = map[1][i] ;
}
que.push( Node1(0,1) ) ;
dis[1] = 0 ;
for(int i=1;i<=N;i++){
while(vis[que.top().num]==1) que.pop() ;
int min_n = que.top().num ;
int _min = que.top().d ;
que.pop() ;
vis[min_n] = 1 ;
if(min_n == N) return _min ;
for(int j=1;j<=N;j++){
if(vis[j]==1 || with[j]==0) continue ;
if(dis[j] > dis[min_n] + map[min_n][j] ){
dis[j] = dis[min_n] + map[min_n][j] ;
que.push( Node1(dis[j] , j) ) ;
}
}
}
}
void solve(){
for(int i=1;i<=N;i++){
for(int j=i;j<=N;j++){
memset(with ,0 ,sizeof(with) );
int min_len = node[i].h ;
int max_len = node[j].h ;
for(int k=1;k<=N;k++){ //选出满足条件的点
if(node[k].h >= min_len && node[k].h<=max_len){
with[ node[k].num ] = 1;
}
}
if(with[1]==0 || with[N]==0) continue ;
Dij() ;
if(dis[N] != INF){
if(max_len - min_len < min_h){
min_h = max_len - min_len ;
min_d = dis[N] ;
}
else if(max_len - min_len == min_h){
if(min_d > dis[N])
min_d = dis[N] ;
}
}
}
}
printf("%d %d\n",min_h,min_d);
}
int main(){
int a ,b, c;
scanf("%d",&T);
while(T--){
scanf("%d %d",&N,&M);
for(int i=1;i<=N;i++){
scanf("%d",&node[i].h);
node[i].num = i ;
}
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
if(i == j) map[i][j] = 0 ;
else map[i][j] = INF ;
}
}
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 ;
}
}
sort(node+1, node+1+N , comp);
min_h = INF ; min_d = INF ;
solve();
}
return 0 ;
}