洛谷 P1967货车运输 并查集+贪心 不需要用LCA!
生活随笔
收集整理的這篇文章主要介紹了
洛谷 P1967货车运输 并查集+贪心 不需要用LCA!
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接
題目鏈接
題解
要求所有的路徑中最小邊長的最大值!
我們貪心的加邊,依照邊從大往小的方式往里添加,然后合并并查集。
每次當查詢分布在兩個待合并的并查集的時候,當前的邊長就是這次查詢的答案。
我們對每個并查集維護一個集合,集合中保存的內容就是一個點在這個并查集中,而另一個點不在這個并查集中的詢問編號。
當待合并的兩個并查集所具有的集合里面擁有相同的詢問編號時候,回答這個詢問編號,然后把小的集合向大的集合合并,并將回答完的詢問編號從集合中移除。
這是一個離線算法。
代碼
#include <bits/stdc++> using namespace std; int n,m,q; set<int>::iterator it; const int maxm = 50005; const int maxn = 11111; set<int> Q[11111]; struct edge{int u,v,cost;friend bool operator <(edge e1,edge e2){return e1.cost > e2.cost;} }es[maxm]; int ans[maxm]; int parent[maxn]; int find(int x){return x == parent[x]?x:parent[x] = find(parent[x]); } int main(){memset(ans,-1,sizeof(ans));for(int i = 1;i < maxn;++i)parent[i] = i;scanf("%d%d",&n,&m);for(int i = 0;i < m;++i)scanf("%d%d%d",&es[i].u,&es[i].v,&es[i].cost);sort(es,es+m);scanf("%d",&q);for(int i = 0;i < q;++i){int x,y;scanf("%d%d",&x,&y);Q[x].insert(i);Q[y].insert(i);}for(int i = 0;i < m;++i){int x = es[i].u,y = es[i].v,c = es[i].cost;int px = find(x),py = find(y);if(px == py) continue;else{if(Q[px].size() > Q[py].size())swap(px,py);vector<int> tmp;for(it = Q[px].begin();it != Q[px].end();++it){int id = *it;if(Q[py].count(id)){ans[id] = c;tmp.push_back(id);}Q[py].insert(id);}for(int i = 0;i < tmp.size();++i)Q[py].erase(tmp[i]);parent[px] = py;}}for(int i = 0;i < q;++i)printf("%d\n",ans[i]); } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的洛谷 P1967货车运输 并查集+贪心 不需要用LCA!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小米14外观正式公布!6.36吋超窄直屏
- 下一篇: 《合金装备:大师合集 Vol.1》游戏媒