@Macw07 5e6条边,你试试???
2024-07-20 17:55:56
发布于:浙江
82阅读
0回复
0点赞
这题我能说什么呢?
真的只有最小生成树但有5e6条边
再加上开头一行or多行(不知道到底有没有)的字符,就这东东咋子做嘛?!
prim和kruscal都是O(ElogE),5e6 * log(5e6)=11180339887这个数?
二叉堆prim,是O(ElogV),5e6*log(2000)=223606797卡常可能也能做,但他是个普及-啊
出题人良心发现了,决定出的简单一点。
确实简单了哈,都不用做了,肯定简单啊
哎,附上我的代码:(kruscal)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
const int mod=1e9+7;
struct Node {
int x, y, z;
} edge[maxn];
bool cmp(Node a, Node b) {
return a.z < b.z;
}//排序要用,按长度排
int n, m, u, v, w, f[maxn];
long long sum;
int find(int x) {
if (x == f[x])return x;//溯到源就return掉
else f[x] = find(f[x]);//往上找
}//查找
void hb(int i) {
int fx = find(edge[i].x), fy = find(edge[i].y);//两个点都溯源
if (fx == fy)return;//已连接就不管
f[fy] = fx;
sum =(sum+ edge[i].z)%mod;//这先取个模以防爆int,同时加到总长
}//合并
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
string tmp;
cin >> tmp;
cin >> n >> m;
for (int i = 1; i <= m; ++i)
cin >> edge[i].x >> edge[i].y >> edge[i].z;
for (int i = 1; i <= n; i ++)
f[i] = i;//并查集日常初始化
sort(edge + 1, edge + m + 1, cmp);//排个序
for (int i = 1; i <= m; i ++)
hb(i);//一个个看看有没有合并
for (int i = 1, ans = 0; i <= n; i ++) {
if (i == f[i]) {
ans++;
if (ans > 1) {
cout << "impossible" << endl;
return 0;
}//正常只有一个点还连自己,否则就是有点没连
}
}
cout << sum%mod << endl;//再模一遍
return 0;
}
希望有大佬给出标程(再@Macw07一遍)
全部评论 7
朴素prim能过,n^2(虽然我懒得写c的),问的,没必要堆优化。
虽然我不知道为啥是橙牌的
2024-08-05 来自 四川
0prim不是n^2吗
2024-08-05 来自 四川
0呜呜呜终于遇到月计人了呀兄弟们
2024-08-05 来自 浙江
0@Macw07
2024-07-20 来自 浙江
0@Macw07
2024-07-20 来自 浙江
0顶
2024-07-20 来自 浙江
0顶
2024-07-20 来自 浙江
0
有帮助,赞一个