当前位置:   article > 正文

leetcode 1319.连通网络的操作次数

leetcode 1319.连通网络的操作次数

思路:DFS(连通块)

其实一开始的时候,并不知道这道题的精髓在哪,总想着,啊?这怎么用图论的思想做啊?

细细思考之后,这道题还是比较有意思的,需要有一定的数据结构基础

这里让我们求最少连接的操作次数。我们其实可以把这些点统统看成是连通块。

例如第一个例子,0,1,2是不是连在一块了?3是不是独立成一块?也就是说,这个例子里面,有两个连通块。我们需要用几条线来连接?我们发现,只需要一条。也就说,2个连通块需要一条来连接,这样全部点都可以访问;如果是3个连通块呢?其实你已经能推出来了,就是2条。

其实这就跟树一样,n个顶点,至少需要n-1边才能成树(树也是图的一种)。这里就运用了这样的数据结构的基础知识。

好了,我们的任务其实就很明确了,找出有多少块连通块;然后,我们需要统计总共给了我们多少条线;最后,我们需要判断连通这些点的最小线数,然后判断一下题目中给我们的线够不够用。

第一个问题很好解决,dfs遍历,然后用一个全局变量统计就行,不要忘记每次dfs的时候需要更新这个变量;

第二个问题,极其的简单,就是connections的二维数组大小。

第三个问题,我们需要着重注意一下细节,首先,我们需要知道一个连通块最少需要多少条线,其实就是上面的知识点,n个顶点的话n-1个就够了,就能至少形成一个连通块。这样的话,我们其实就是重新统计了一遍每个连通块所用的条数,然后相加到sum中,判断总条数-sum,就是我们能够最大限度用的线了。如果说,我们剩下的线足够我们连通这几个连通块,那么就取能够连通这几个连通块的最小条数,而不取剩下的条数;否则,就不能连接上。

注意:你需要额外定义一个二维数组存储各顶点的联通关系。

上代码:

  1. class Solution {
  2. public:
  3. int counts=0;
  4. void dfs(int u,vector<vector<int>>&s,vector<bool>&st){
  5. for(int i=0;i<s[u].size();i++){
  6. int tmp=s[u][i];
  7. if(!st[tmp]){
  8. st[tmp]=true;
  9. counts++;
  10. dfs(tmp,s,st);
  11. }
  12. }
  13. }
  14. int makeConnected(int n, vector<vector<int>>& connections) {
  15. int res=0;
  16. vector<vector<int>>s(n);
  17. vector<bool>st(n,false);
  18. vector<int>ans;
  19. for(int i=0;i<connections.size();i++){
  20. int x=connections[i][0];
  21. int y=connections[i][1];
  22. s[x].emplace_back(y);
  23. s[y].emplace_back(x);
  24. }
  25. for(int i=0;i<n;i++){
  26. if(!st[i]){
  27. st[i]=1;
  28. res++;
  29. dfs(i,s,st);
  30. }
  31. ans.push_back(counts);
  32. counts=0;
  33. }
  34. int sum=0;
  35. for(int i=0;i<ans.size();i++){
  36. sum+=ans[i];
  37. }
  38. if(connections.size()>=sum)
  39. return connections.size()-sum>=res-1?res-1:-1;
  40. else
  41. return -1;
  42. }
  43. };

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/570271
推荐阅读
相关标签
  

闽ICP备14008679号