find the most comfortable road (并查集+路径枚举

XX星有许多城市,城市之间通过一种奇怪的高速公路SARS(Super Air Roam Structure---超级空中漫游结构)进行交流,每条SARS都对行驶在上面的Flycar限制了固定的Speed,同时XX星人对 Flycar的“舒适度”有特殊要求,即乘坐过程中最高速度与最低速度的差越小乘坐越舒服 ,(理解为SARS的限速要求,flycar必须瞬间提速/降速,痛苦呀 ),
但XX星人对时间却没那么多要求。要你找出一条城市间的最舒适的路径。(SARS是双向的)。 

贪心思想:路径上权值极差越小,它们的权值按顺序排序后之间的距离越小,按权值排序,逐个添加路径直到目标点连通(用并查集判断),这个过程也是构造最小生成树的过程,因为答案不一定在最小生成树上,因此枚举最小生成树的初始节点,逐个构造,找到答案

枚举过程:

        for( i=0 ;i<m ;i++){    //枚举初始边p i
             init( n); flag = 0;
             for( j=i ;j<m ;j++){ //构造最小生成树
                 add( p[j].u ,p[j].v);
                 if( find( am)==find( an)){flag = 1;break;}
            }
            if( flag) ans=min( ans ,p[j].cost -p[i].cost);
        }

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int inf = 0x3f3f3f3f;

struct node{
     int u, v, cost;
     bool operator < ( const node & r) const{
         return cost < r.cost;
     }
} p[10000];
int pre[2000];

int find( int x){
     return  pre[x] == x ? x : pre[x] =find( pre[x] );
}

void add( int x ,int y){
     int a= find( x);
     int b= find( y);
     if( a!=b){
        pre[a] = b;
     }
}

void init( int x){
     for( int i=0 ;i<=x ;i++)
        pre[i] = i;
}
int main( ){
     int n ,m;
    while(~ scanf( "%d%d" ,&n ,&m)){
     for( int i=0 ;i<m ;i++){
        scanf("%d%d%d" ,&p[i].u ,&p[i].v ,&p[i].cost );
     }
     sort( p ,p+m);
     int t; scanf("%d" ,&t);
     while( t--){
            int am ,an ,ans=inf;
            int flag=0;
            scanf("%d%d" ,&am,&an);
         int i ,j;
         for( i=0 ;i<m ;i++){
             init( n); flag = 0;
             for( j=i ;j<m ;j++){
                 add( p[j].u ,p[j].v);
                 if( find( am)==find( an)){flag = 1;break;}
            }
            if( flag) ans=min( ans ,p[j].cost -p[i].cost);
        }
        if( ans==inf) printf("-1\n");
        else printf("%d\n" ,ans);
     }
    }
     return 0;
}

猜你喜欢

转载自www.cnblogs.com/-ifrush/p/10656220.html