Hihocoder 1561 观光旅行(启发式合并+贪心)
题目链接 Hihocoder 1561
首先对原图求MST
我们发现某条边成为某两个点的关键路径的必要条件是这条边是最小生成树的树边。
所以我们求MST的同时进行启发式合并。
把size小的子树合并到size大的子树当中就可以了。
接下来是处理询问。
对于一条边,如果他不是最小生成树的树边,则答案为0 0
考虑这条边的两边的所有点。
我们先在B集合中求出最大的y
然后在A集合中求出最大的小于y的x
然后再在B集合中求出最小的大于x的y
这样就符合了题目的这个条件:
x<y
且如果有多个满足条件的 x 和 y,输出其中 x 最大的,如果还有多个满足条件的,输出其中 y 最小的。
时间复杂度 O(nlog2n)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) #define MP make_pair #define fi first #define se second typedef long long LL; const int N = 2e5 + 10; int father[N], sz[N]; set < int > s[N]; int n, m; pair < int , int > ans[N << 1]; struct node{ int x, y, z, id; void scan(){ scanf ( "%d%d%d" , &x, &y, &z);} friend bool operator < ( const node &a, const node &b){ return a.z < b.z; } } e[N << 1]; int getfather( int x){ return father[x] ? father[x] = getfather(father[x]) : x; } void update( int i, int x, int y){ if (!s[x].size()) return ; if (!s[y].size()) return ; int ny = *--s[y].end(); set < int > :: iterator it = s[x].lower_bound(ny); if (it == s[x].begin()) return ; int px = *--it; int py = *s[y].lower_bound(px); if (px > ans[i].fi || px == ans[i].fi && py < ans[i].se) ans[i] = MP(px, py); } int main(){ scanf ( "%d%d" , &n, &m); rep(i, 1, n) sz[i] = 1; rep(i, 1, n) s[i].insert(i); rep(i, 1, m){ e[i].scan(); e[i].id = i; } sort(e + 1, e + m + 1); rep(i, 1, m){ int x = e[i].x, y = e[i].y; int fa = getfather(x); int fb = getfather(y); if (fa == fb) continue ; if (sz[fa] < sz[fb]) swap(fa, fb), swap(x, y); update(e[i].id, fa, fb); update(e[i].id, fb, fa); for ( auto it : s[fb]) s[fa].insert(it); s[fb].clear(); father[fb] = fa; sz[fa] += sz[fb]; } rep(i, 1, m) printf ( "%d %d\n" , ans[i].fi, ans[i].se); return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】博客园携手 AI 驱动开发工具商 Chat2DB 推出联合终身会员
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 依赖注入中的 Captive Dependency
· .NET Core 对象分配(Alloc)底层原理浅谈
· 聊一聊 C#异步 任务延续的三种底层玩法
· 敏捷开发:如何高效开每日站会
· 为什么 .NET8线程池 容易引发线程饥饿
· 终于决定:把自己家的能源管理系统开源了!
· 外部H5唤起常用小程序链接规则整理
· C#实现 Winform 程序在系统托盘显示图标 & 开机自启动
· 了解 ASP.NET Core 中的中间件
· 详解:订单履约系统规划