网易4.16笔试通用技术第三题
大概题意就是给几个点几个边问删除边获得的最大权值数
权值计算方法是两个点的权值相乘后数字末尾0的个数
其实就是一个求最小生成树的题,求删边的最大权值就是求生成一个最小权值的树,kruskal算法即可
笔试服务器崩了不知道此题ac情况,但是我觉得此题***不离十是这么写的
#include<bits/stdc++.h> using namespace std; class unionSet{ public: int *fa, n; unionSet(int n) : n(n){ fa = new int[n + 1]; for(int i = 0; i <= n; i++) fa[i] = i; } int find(int x) {return fa[x] = (fa[x] == x ? x : find(fa[x]));} void merge(int a, int b){fa[find(a)] = find(b);} }; struct edge{ int s, e, v; }; bool cmp(const edge& a, const edge& b){ return a.v < b.v; } edge edg[200005]; int n, m, cnt, edg_cnt, num[200005], res, sum; void add_edge(int s, int e){ int ret = 0; edg[edg_cnt].s = s; edg[edg_cnt].e = e; int t = num[s] * num[e]; string str = to_string(t); for(auto x : str) { if(x == '0') ret++; } edg[edg_cnt].v = ret; sum += ret; edg_cnt++; } int main(){ cin >> n >> m; for(int i = 1; i <= n; i++){ cin >> num[i]; } for(int i = 0; i < m; i++){ int a, b; cin >> a >> b; add_edge(a, b); } sort(edg, edg + m, cmp); unionSet u(n); for(int i = 0; i < m; i++){ int s = edg[i].s, e = edg[i].e, v = edg[i].v; if(u.find(s) != u.find(e)){ u.merge(s, e); res += v; cnt++; if(cnt == n - 1){ cout << sum - res << endl; return 0; } } } cout << "orz" << endl; return 0; }
#网易笔试##实习##春招##笔试题目#