hdu 1598 find the most comfortable road(并查集)
题意:略
分析:多询问问题,利用并查集加速。类似于kruskal对MST的构建:枚举最小的边,逐渐将更大的边加入集合,当查询的点在同一个集合,那么当前最小值,就是所加的最后一条边与第一条只差。
注意:当枚举的最小边,把所有大边加入都不能使查询点(a,b)加入同一集合,那么终止枚举。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 const int MAXN=1111; 7 const int INF=0x7fffffff; 8 9 struct Edge{ 10 int u,v,c; 11 Edge(){} 12 Edge(int _u,int _v,int _c):u(_u),v(_v),c(_c){} 13 }edge[MAXN]; 14 15 int n,m; 16 int p[222]; 17 18 int cmp(Edge a,Edge b) 19 { 20 return a.c<b.c; 21 } 22 23 void init() 24 { 25 for(int i=1;i<=n;i++) 26 p[i]=i; 27 } 28 29 int find(int x) 30 { 31 return p[x]==x?x:p[x]=find(p[x]); 32 } 33 34 int main() 35 { 36 while(~scanf("%d%d",&n,&m)) 37 { 38 for(int i=0;i<m;i++) 39 { 40 int u,v,c; 41 scanf("%d%d%d",&u,&v,&c); 42 edge[i]=Edge(u,v,c); 43 } 44 sort(edge,edge+m,cmp); 45 46 int q; 47 scanf("%d",&q); 48 while(q--) 49 { 50 int mi=INF,a,b; 51 scanf("%d%d",&a,&b); 52 for(int i=0;i<m;i++) 53 { 54 init(); 55 int j; 56 for(j=i;j<m;j++) 57 { 58 int u=edge[j].u; 59 int v=edge[j].v; 60 int x=find(u); 61 int y=find(v); 62 if(x!=y) 63 p[x]=y; 64 if(find(a)==find(b)) 65 break; 66 } 67 if(j==m) 68 break; 69 mi=min(mi,edge[j].c-edge[i].c); 70 } 71 if(mi==INF) 72 printf("-1\n"); 73 else 74 printf("%d\n",mi); 75 } 76 } 77 return 0; 78 }