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; }