2024“钉耙编程”中国大学生算法设计超级联赛(8)1006 cats 的最小生成树
题目大意 :给出有
思路 :由于构成最小生成树的边数是
#include <bits/stdc++.h>
const double eps = 1e-6;
using namespace std;
const int N = 1e5 + 10;
const int M = 5e4 + 10;
#define int long long
struct node {
int u, v, val;
};
void solve() {
int n, m;
cin >> n >> m;
vector<vector<int> > fa(m / (n - 1) + 1, vector<int>(n + 1));
vector<node> E(m + 1);
vector<int> ans(m + 1), cnt(m + 1);
function<int(int, int)> findf = [&](int x, int c) -> int {
if (fa[c][x] == x) return x;
else return fa[c][x] = findf(fa[c][x], c);
};
for (int j = 0; j <= (m / (n - 1)); j++) {
for (int i = 1; i <= n; i++) {
fa[j][i] = i;
//cout<<"fa[" << j <<"]["<<i << "]="<<fa[j][i]<<'\n';
}
}
//cout << fa[1][1] << '\n';
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
E[i] = {u, v, i};
}
for (int i = 1; i <= m; i++) {
auto [u, v, w] = E[i];
int l = 1, r = m / (n - 1);
int idx = -1;
while (l <= r) {
int mid = (l + r) >> 1;
//cout << findf(u, mid) << ' ' << findf(v, mid) << '\n';
if (findf(u, mid) == findf(v, mid)) {
l = mid + 1;
} else {
idx = mid;
r = mid - 1;
}
}
if (idx != -1) {
fa[idx][findf(u, idx)] = findf(v, idx);
cnt[idx]++;
}
ans[i] = idx;
}
for (int i = 1; i <= m; i++) {
if (ans[i] == -1) cout << -1;
else if (ans[i] == m / (n - 1) + 1 || cnt[ans[i]] != n - 1) cout << "-1";
else cout << ans[i];
cout << ' ';
}
cout << '\n';
}
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
cin >> _;
while (_--) solve();
}
分类:
解题报告 / 2024暑假杭电
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!