基于贪心的思想,我们应当优先删除仅Alice或者仅Bob通过的边,尽可能的保留下二者都可通行的公共边。因此,我们对所有的边排序,把公共边都放在前边,然后用并查集维护连通性。
先对Alice能在图上通过的边都遍历一遍,用并查集来维护点之间的连通性,如果已经连通,则说明该边可以删除,对该边打上标记。然后枚举所有点,看看并查集中有多少个连通块,如果大于一个,说明Alice无法到达整个图,返回-1。
同理,再对Bob进行如上操作。
最后统计一下所有被打上标记的边即可。
- class Solution {
- public:
- vector<int> p=vector<int>(100010);
- int findd(int x){
- return p[x]==x?x:p[x]=findd(p[x]);
- }
- void unionn(int x,int y){
- p[findd(x)]=findd(y);
- }
- int maxNumEdgesToRemove(int n, vector
int >>& edges) { - sort(edges.begin(),edges.end(),[](const auto &a,const auto &b){
- return a[0]>b[0];
- });
- int m=edges.size();
- vector<int> d(m,0);
- int ans=0;
- iota(p.begin(),p.end(),0);
- for(int i=0;i
- if(edges[i][0]==2) continue;
- int x=findd(edges[i][1]),y=findd(edges[i][2]);
- if(x==y) d[i]=1;
- else unionn(x,y);
- }
- int cnt=0;
- for(int i=1;i<=n;i++) if(p[i]==i) cnt++;
- if(cnt>1) return -1;
- cnt=0;
- iota(p.begin(),p.end(),0);
- for(int i=0;i
- if(edges[i][0]==1) continue;
- int x=findd(edges[i][1]),y=findd(edges[i][2]);
- if(x==y) d[i]=1;
- else unionn(x,y);
- }
- for(int i=1;i<=n;i++) if(p[i]==i) cnt++;
- if(cnt>1) return -1;
- for(int i=0;i
if(d[i]) ans++; - return ans;
- }
- };
时间复杂度:O(n+m·α(n)),α(n)为并查集操作的复杂度
空间复杂度:O(n)
-
相关阅读:
yum命令中的gcc是什么含义?答:是一种包,并不是参数。
联邦学习论文分析1----联邦学习_功率分配_频带分配_传输速率_能耗
趣玩行为商城:用智能消费行为开启财富新生活!
云计算(Cloud Computing)
JAVA1年经验技术栈列表
汽车OTA测试思考与实践
Linux网络管理
【技术积累】软件工程中的测试驱动开发【一】
3.字符串
centos7.x本地挂载阿里云oss
-
原文地址:https://blog.csdn.net/aaa7888210/article/details/128201851