地址:
点击打开链接
这个题目,怎么说呢,一开始我看到这个题目,想到的时,把高度替换一下,然后找最短路,记录下路径,随后再去找真的最短路。后来发现不太可行,因为可能不止一个。而且也不太好判断。于是网上找了一波,不太习惯spfa算法,还是习惯dj。所以找到了一个,还没有来得及敲代码。整体思路,就是把所有的高度差都列一遍,然后dj看能不能到,能到就更新,不能到接着算。
#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 ; }