感觉思路没有问题,为何只能过部分样例?

题目传送门

基本思路是使用优先队列(大根堆)来存储边的信息,并按照边的权值乘积末尾0的数量进行排序。然后,从大到小依次考虑每条边,如果边连接的两个节点的度都大于1,则可以删去该边,并将其权值乘积末尾0的数量累加到最终的答案中。

这段代码的时间复杂度为O(mlogm),其中m为边的数量。

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
using ll=long long;
const int N=1e5+10;
vector<int> G[N];//邻接表存图
ll a[N];//记录每个点的权值
int d[N];//记录每个点的度
struct Edge {
    int weight;
    int startVertex;
    int endVertex;
    bool operator<(const Edge& other) const {
        return weight < other.weight;
    }
};
priority_queue<Edge> q;
int n,m;
int ans;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=m;i++){
        int u,v;
        cin>>u>>v;
        G[u].push_back(v);
        G[v].push_back(u);
        d[u]++;
        d[v]++;
        ll num=a[u]*a[v];
        int w=0;
        while(num%10==0){
            w++;
            num/=10;
        }
        q.push({w,u,v});
    }
    while(q.size()){
        auto t=q.top();
        q.pop();
        int w=t.weight,s=t.startVertex,e=t.endVertex;
        if(d[s]>1&&d[e]>1){
            ans+=w;
            d[s]--;
            d[e]--;
        }
    }
    cout<<ans;
    return 0;
}

感谢,评论区“卖冰糖葫芦的大叔”的解惑,对于本题一言以蔽之:求一个连通图的最小生成树,题目要的答案——不过就是所有边权值减去最小生成树的权值罢了,n、m数量级一致,稀疏图,使用克鲁斯卡尔算法即可。判断图的连通可以使用并查集~

全部评论
思路有点问题,并不是每个度都是1就是连通图
点赞 回复 分享
发布于 2023-12-03 21:29 广东

相关推荐

Bug压路:老哥看得出来你是想多展示一些项目,但好像一般最多两个就够了😂页数一般一页,多的也就2页;这些项目应该是比较同质化的,和评论区其他大佬一样,我也觉得应该展示一些最拿手的(质量>数量)😁😁😁专业技能部分也可以稍微精简一些
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务