find the most comfortable road HDU - 1598
考察:枚举+最小生成树
错误思路:
根据最小生成树建立邻接表.每次询问就dfs...这解法我没做出来.图的dfs还不太熟.等之后熟了再补吧.
正确思路:
每次询问求i,j最大权值与最小权值的差.实际就是问最小生成树上i到j的最大权值与最小权值的差.这道题可以直接枚举.参考上一题当i,j在一个集合中就说明他们在最小生成树里.我们枚举每一条边作为搭建的起始边.当i,j在集合里就说明找到了一个解.求解的最小值
如果是跳跃式选边的话会增大极差的值
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 const int N = 210,M = 1010; 6 int p[N],n,m,q; 7 struct Edge{ 8 int u,v,w; 9 bool operator<(Edge x){ 10 return this->w<x.w; 11 } 12 }edge[M]; 13 int findf(int x) 14 { 15 if(x!=p[x]) p[x] = findf(p[x]); 16 return p[x]; 17 } 18 int main() 19 { 20 while(scanf("%d%d",&n,&m)!=EOF) 21 { 22 for(int i=0;i<m;i++) 23 scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w); 24 sort(edge,edge+m); 25 scanf("%d",&q); 26 for(int w=0;w<q;w++){ 27 int s,e,ans = 0x3f3f3f3f; 28 scanf("%d%d",&s,&e); 29 for(int j=0;j<m;j++){ 30 for(int i=1;i<=n;i++) p[i] = i; 31 for(int k=j;k<m;k++){ 32 int x = findf(edge[k].u),y = findf(edge[k].v); 33 if(x!=y) p[x] =y; 34 if(findf(s)==findf(e)) { ans = min(ans,edge[k].w-edge[j].w); break; } 35 } 36 } 37 if(ans==0x3f3f3f3f) printf("-1\n"); 38 else printf("%d\n",ans); 39 } 40 } 41 return 0; 42 }