【问题描述】
在某个遥远的国家里,有n个城市。编号为1,2,3,…,n。这个国家的政府修建了m条双向道路,每条道路连接着两个城市。政府规定从城市S到城市T需要收取的过路费为所经过城市之间道路长度的最大值。如:A到B长度为2,B到C长度为3,那么开车从A经过B到C需要上交的过路费为3。 _佳佳是个做生意的人,需要经常开车从任意一个城市到另外一个城市,因此他需要频繁地上交过路费,由于忙于做生意,所以他无时间来寻找交过路费最低的行驶路线。然而,当他交的过路费越多他的心情就变得越糟糕。作为秘书的你,需要每次根据老板的起止城市,提供给他从开始城市到达目的城市,最少需要上交多少过路费。 _
【输入格式】
第一行是两个整数n 和m,分别表示城市的个数以及道路的条数。
接下来m行,每行包含三个整数 _a,b,w(1≤a,b≤n,0≤w≤10^9),表示a与b之间有一条长度为w的道路。
接着有一行为一个整数q,表示佳佳发出的询问个数。
再接下来q行,每一行包含两个整数S,T(1≤S,T≤n,S≠T), 表示开始城市S和目的城市T。
【输出格式】
输出文件共q行,每行一个整数,分别表示每个询问需要上交的最少过路费用。输入数据保证所有的城市都是连通的。 _
【样例输入】
4 5
1 2 10
1 3 20
1 4 100
2 4 30
3 4 10
2
1 4
4 1
【样例输出】
20
20
对于30%的数据,n<=1000,m<=10000,q<=100
对于50%的数据,n<=10000,m<=10000,q<=10000
对于100%的数据,n<=10000,m<=100000,q<=10000
solution:跑最小生成树,倍增
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define N (20020) 6 #define INF (2000000010) 7 using namespace std; 8 struct orz{ 9 int x,y,val; 10 void Read(){ 11 scanf("%d %d %d",&x,&y,&val); 12 } 13 bool operator < (const orz &A) const{ 14 return val<A.val; 15 } 16 }Gra[N]; 17 struct edge{ 18 int next,to,val; 19 void Add(int Next,int To,int V){ 20 next=Next; to=To; val=V; 21 } 22 }q[N]; 23 int n,m,fa[N],m1,dep[N],f[N][30],A[N],T[N][30],h[N]; 24 int fin(int x){ 25 if (x==fa[x]) return x; 26 fa[x]=fin(fa[x]); 27 return fa[x]; 28 } 29 void addedge(int x,int y,int val){ 30 q[++m1].Add(h[x],y,val); h[x]=m1; 31 q[++m1].Add(h[y],x,val); h[y]=m1; 32 } 33 void Dfs(int x){ 34 for (int i=h[x];i;i=q[i].next){ 35 int y=q[i].to; 36 if (y==fa[x]) continue; 37 fa[y]=x; dep[y]=dep[x]+1; A[y]=q[i].val; 38 Dfs(y); 39 } 40 } 41 int main(){ 42 cin>>n>>m; 43 int i,j; 44 for (i=1;i<=m;i++) Gra[i].Read(); 45 sort(Gra+1,Gra+m+1); 46 for (i=1;i<=n;i++) fa[i]=i; 47 for (i=1;i<=m;i++){ 48 if (fin(Gra[i].x)==fin(Gra[i].y)) continue; 49 fa[fin(Gra[i].x)]=fin(Gra[i].y); 50 addedge(Gra[i].x,Gra[i].y,Gra[i].val); 51 } 52 memset(fa,0,sizeof(fa)); 53 Dfs(1); 54 for (i=1;i<=n;i++) f[i][0]=A[i],T[i][0]=fa[i]; 55 for (j=1;j<=15;j++) 56 for (i=1;i<=n;i++){ 57 T[i][j]=T[T[i][j-1]][j-1]; 58 f[i][j]=max(f[i][j-1],f[T[i][j-1]][j-1]); 59 } 60 int x,y,Q; cin>>Q; 61 while (Q--){ 62 scanf("%d %d",&x,&y); 63 if (dep[x]<dep[y]) swap(x,y); 64 if (x==y){ 65 cout<<0<<endl; continue; 66 } 67 int ans=0; 68 for (i=15;i>=0;i--){ 69 if (dep[T[x][i]]>=dep[y]){//写成<=了 70 ans=max(ans,f[x][i]); 71 x=T[x][i]; 72 } 73 } 74 if (x==y){ 75 printf("%d\n",ans); 76 continue; 77 } 78 for (i=15;i>=0;i--){ 79 if (T[x][i]!=T[y][i]) { 80 ans=max(ans,f[x][i]); 81 ans=max(ans,f[y][i]); 82 x=T[x][i]; y=T[y][i]; 83 } 84 } 85 ans=max(ans,f[x][0]); ans=max(ans,f[y][0]);//这两句漏了 86 printf("%d\n",ans); 87 } 88 }