日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Kruskal+LCA【p2245】 星际导航

發布時間:2024/10/12 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Kruskal+LCA【p2245】 星际导航 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Description

sideman做好了回到Gliese 星球的硬件準備,但是sideman的導航系統還沒有完全設計好。為了方便起見,我們可以認為宇宙是一張有\(N\) 個頂點和\(M\) 條邊的帶權無向圖,頂點表示各個星系,兩個星系之間有邊就表示兩個星系之間可以直航,而邊權則是航行的危險程度。

sideman 現在想把危險程度降到最小,具體地來說,就是對于若干個詢問(A, B),sideman 想知道從頂點\(A\) 航行到頂點\(B\) 所經過的最危險的邊的危險程度值最小可能是多少。作為sideman 的同學,你們要幫助sideman 返回家園,兼享受安全美妙的宇宙航行。所以這個任務就交給你了。

Input

第一行包含兩個正整數\(N\)\(M\),表示點數和邊數。

之后 \(M\) 行,每行三個整數\(A\),$B \(和\)L\(,表示頂點\)A$ 和\(B\) 之間有一條邊長為\(L\) 的邊。頂點從\(1\) 開始標號。

下面一行包含一個正整數 \(Q\),表示詢問的數目。

之后 \(Q\) 行,每行兩個整數\(A\)\(B\),表示詢問\(A\)\(B\) 之間最危險的邊危險程度的可能最小值。

Output

對于每個詢問, 在單獨的一行內輸出結果。如果兩個頂點之間不可達, 輸出\(impossible\)

woc這不是\(Noip\ 2013\)貨車運輸.

切掉!

顯然,我們可以發現.想要讓一些頂點聯通,并且讓最危險的邊的危險程度值最小。

優先想到了\(Kruskal\).

首先\(Kruckal\)建樹。

如何求兩點間的距離?帶權\(LCA\)即可.

如果兩點不在一顆樹,要輸出\(impossible\)!!

剛開始輸出錯了

注意如果寫兩個結構體的話,對其中一個\(Sort\)(建樹)的話,不要結構體中重載\(<\)

代碼

#include<cstdio> #include<algorithm> #include<cctype> #define R register #define N 100008 using namespace std; inline void in(int &x) {int f=1;x=0;char s=getchar();while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}while(isdigit(s)){x=x*10+s-'0';s=getchar();}x*=f; } int n,m,head[N],tot,q; int fa[N],cnt,depth[N],f[N][21],gw[N][21]; struct cod{int u,v,w;}edge[300010],tree[300010]; inline bool ccp(const cod&a,const cod&b) {return a.w<b.w; } int find(int x){return fa[x]==x ? x : fa[x]=find(fa[x]);} inline void add(int x,int y,int z) {edge[++tot].u=head[x];edge[tot].v=y;edge[tot].w=z;head[x]=tot; } inline void kruskal() {for(R int i=1;i<=n;i++)fa[i]=i;sort(tree+1,tree+m+1,ccp);for(R int i=1;i<=m;i++){int u=tree[i].u,v=tree[i].v,w=tree[i].w;int fu=find(u),fv=find(v);if(fu==fv)continue;add(u,v,w);add(v,u,w);fa[fu]=fv;cnt++;if(cnt==n-1)break;}return ; } void dfs(int u,int fat,int dis) {depth[u]=depth[fat]+1;gw[u][0]=dis;f[u][0]=fat;for(R int i=1;(1<<i)<=depth[u];i++){f[u][i]=f[f[u][i-1]][i-1];gw[u][i]=max(gw[u][i-1],gw[f[u][i-1]][i-1]);}for(R int i=head[u];i;i=edge[i].u){if(edge[i].v==fat)continue;dfs(edge[i].v,u,edge[i].w);} } inline int lca(int x,int y) {int res=-214748364;if(depth[x]>depth[y])swap(x,y);for(R int i=20;i>=0;i--)if(depth[x]+(1<<i)<=depth[y])res=max(res,gw[y][i]),y=f[y][i];if(x==y)return res;for(R int i=20;i>=0;i--){if(f[x][i]==f[y][i])continue;res=max(res,gw[x][i]);res=max(res,gw[y][i]);x=f[x][i],y=f[y][i];}return max(max(res,gw[x][0]),gw[y][0]); } int main() {in(n),in(m);for(R int i=1;i<=m;i++)in(tree[i].u),in(tree[i].v),in(tree[i].w);kruskal();dfs(1,0,0);in(q);for(R int i=1,x,y;i<=q;i++){in(x),in(y);R int fx=find(x),fy=find(y);if(fx!=fy)puts("impossible");else printf("%d\n",lca(x,y));} }

轉載于:https://www.cnblogs.com/-guz/p/9769005.html

總結

以上是生活随笔為你收集整理的Kruskal+LCA【p2245】 星际导航的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。