http://codevs.cn/problem/1519/?
? ? 在某個遙遠的國家里,有 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%的數據,滿足 1≤ n≤1000,1≤m≤10000,1≤q≤100;?
對于 50%的數據,滿足 1≤ n≤10000,1≤m≤10000,1≤q≤10000;?
對于 100%的數據,滿足 1≤ n≤10000,1≤m≤100000,1≤q≤10000;
?
(和貨車運輸很像)
先求出最小生成樹(使圖簡化),在此樹上做倍增,維護最大代價
1 #include <algorithm> 2 #include <cstring> 3 #include <cstdio> 4 5 using namespace std; 6 7 const int N(10000+15); 8 const int M(100000+5); 9 int n,m,q,u,v,ans; 10 struct Edge 11 { 12 int u,v,w; 13 }road[M]; 14 bool cmp(Edge a,Edge b) 15 { 16 return a.w<b.w; 17 } 18 19 int head[N],sumedge; 20 struct E 21 { 22 int v,next,w; 23 E(int v=0,int next=0,int w=0): 24 v(v),next(next),w(w){} 25 }edge[N<<1]; 26 void ins(int u,int v,int w) 27 { 28 edge[++sumedge]=E(v,head[u],w); 29 head[u]=sumedge; 30 } 31 32 int fa[N]; 33 int find(int x) 34 { 35 return x==fa[x]?x:fa[x]=find(fa[x]); 36 } 37 void K() 38 { 39 int cnt=0; 40 sort(road+1,road+m+1,cmp); 41 for(int i=1;i<=n;i++) fa[i]=i; 42 for(int i=1;i<=m;i++) 43 { 44 int x=road[i].u,y=road[i].v; 45 int fx=find(x),fy=find(y); 46 if(fx==fy) continue; 47 fa[fx]=fy; 48 ins(x,y,road[i].w); 49 ins(y,x,road[i].w); 50 if(++cnt==n-1) return ; 51 } 52 } 53 54 int dad[N],val[N],deep[N]; 55 void DFS(int x) 56 { 57 deep[x]=deep[dad[x]]+1; 58 for(int i=head[x];i;i=edge[i].next) 59 { 60 int v=edge[i].v; 61 if(dad[v]) continue; 62 val[v]=edge[i].w; 63 dad[v]=x; DFS(v); 64 } 65 } 66 int LCA(int x,int y) 67 { 68 int maxx=0,maxn=0; 69 if(deep[x]>deep[y]) swap(x,y); 70 for(;deep[y]>deep[x];y=dad[y]) maxx=max(maxx,val[y]); 71 for(;x!=y;x=dad[x],y=dad[y]) maxn=max(maxn,max(val[x],val[y])); 72 return max(maxn,maxx); 73 } 74 75 int main() 76 { 77 scanf("%d%d",&n,&m); 78 for(int i=1;i<=m;i++) 79 scanf("%d%d%d",&road[i].u,&road[i].v,&road[i].w); 80 K(); DFS(1); 81 scanf("%d",&q); 82 for(;q--;) 83 { 84 scanf("%d%d",&u,&v); 85 printf("%d\n",LCA(u,v)); 86 } 87 return 0; 88 }
?