大佬们,怎么判重边啊

P3366 【模板】最小生成树

那就用kruskal
by BMTXLRC @ 2022-07-20 20:28:19


重边就是端点相同的边,对于最小生成树来说应该是不影响的,因为只会取边权最小的一条边
by awcyvan @ 2022-07-20 20:28:22


```cpp #include<bits/stdc++.h> using namespace std; int n,m; int maps[114][514]; bool flag[114514]={0}; int cost[114514]; int minc=INT_MAX; int nxt; int sum=0; bool book; void prim() { for(int i=1;i<=n;i++) { cost[i]=maps[1][i];//将结点一到其他结点的权值保存在cost中 } flag[1]=1;//标记已访问 for(int i=1;i<=n-1;i++)//1已经访问过了,所以循环n-1次 { int minc=INT_MAX; for(int j=1;j<=n;j++) { if(flag[j]==0 && cost[j]< minc) { minc=cost[j];//将该结点到其他结点的权值相互做比较,取最小值 nxt=j;//nxt标记下一个结点 } } if(minc==INT_MAX) { book=1; break; } flag[nxt]=1; sum+=cost[nxt];//将到下一个结点的权值累加 for(int j=1;j<=n;j++) { if(flag[j]==0 && maps[nxt][j]<cost[j])//如果这点没有被访问过,而且这个点到任意一点的距离比现在到树的距离近那么更新 { cost[j]=maps[nxt][j];//将下一个结点到其他结点的权值存在cost中 } } } if(book==1) { cout<<"orz"; return; } cout<<sum; } int main() { cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(i!=j) maps[i][j]=INT_MAX; else maps[i][j]=0; } for(int i=1;i<=m;i++) { int x,y,z; cin>>x>>y>>z; maps[x][y]=z; maps[y][x]=z; } prim(); return 0; } ```
by slipknot @ 2022-07-20 20:31:45


@[awcyvan](/user/691465) 我这段却只得30分,大佬能看看哪出问题了吗
by slipknot @ 2022-07-20 20:32:29


邻接矩阵……有重边的话输入时保留最小的一个边权,因为更大的不会有贡献
by awcyvan @ 2022-07-20 20:34:16


@[slipknot](/user/543953) 那啥,时间过得了吗
by Mr_Terminator @ 2022-07-20 20:34:36


存边时取min(map\[x]\[y],z)
by awcyvan @ 2022-07-20 20:35:02


似乎是O(n^2+m)的暴力版本,拿个堆或者优先队列什么的维护一下最小距离吧
by awcyvan @ 2022-07-20 20:37:41


堆优化的方式类似 Dijkstra 的堆优化,但如果使用二叉堆等不支持 O(1) decrease-key 的堆,复杂度就不优于 Kruskal,常数也比 Kruskal 大。所以,一般情况下都使用 Kruskal 算法,在稠密图尤其是完全图上,暴力 Prim 的复杂度比 Kruskal 优,但 不一定 实际跑得更快。 我的建议是跑 Kruskal
by awcyvan @ 2022-07-20 20:38:53


@[awcyvan](/user/691465) 好的,感谢大佬,等这个过了之后再用Kruskal走一遍
by slipknot @ 2022-07-20 20:40:31


| 下一页