zoukankan      html  css  js  c++  java
  • UnionFind问题总结

    UnionFind就是acm中常用的并查集...

    并查集常用操作

    另外补充一下STL常用操作

    相关问题:

    547. Friend Circles

    纯裸题噢...

     1 class Solution {
     2 public:
     3     int root[210];
     4     bool v[210];
     5 
     6     void uf_init(int x)
     7     {
     8         for(int i=0;i<=x;i++)
     9             root[i]=i;
    10     }
    11 
    12     int uf_find(int x)
    13     {
    14         if(x!=root[x])
    15             root[x]=uf_find(root[x]);
    16         return root[x];
    17     }
    18 
    19     void uf_union(int x, int y)
    20     {
    21         int tx=uf_find(x);
    22         int ty=uf_find(y);
    23         if(tx!=ty)
    24             root[tx]=ty;
    25     }
    26 
    27     int findCircleNum(vector<vector<int>>& M) 
    28     {
    29         int kn=M.size();
    30         uf_init(kn);
    31         for(int i=0;i<kn;i++)
    32             for(int j=i+1;j<kn;j++)
    33                 if(M[i][j])
    34                     uf_union(i,j);
    35 
    36         memset(v,0,sizeof(v));
    37         int cnt=0;
    38         for(int i=0;i<kn;i++)
    39             if(!v[uf_find(i)])
    40             {
    41                 cnt++;
    42                 v[uf_find(i)]=true;
    43             }
    44         return cnt;
    45     }
    46 };
    View Code

    Graph Valid Tree 

    (权限题做不了嘤嘤嘤)

    684. Redundant Connection

    并查集找无向图中的环,比较裸的题

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <vector>
     4 #include <set>
     5 #include <map>
     6 #include <string>
     7 #include <cstring>
     8 #include <cstdio>
     9 using namespace std;
    10 
    11 
    12 class Solution {
    13 public:
    14     int root[1010];
    15 
    16     void uf_init(int x)
    17     {
    18         for(int i=0;i<=x;i++)
    19             root[i]=i;
    20     }
    21 
    22     int uf_find(int x)
    23     {
    24         if(x!=root[x])
    25             root[x]=uf_find(root[x]);
    26         return root[x];
    27     }
    28 
    29     void uf_union(int x, int y)
    30     {
    31         int tx=uf_find(x);
    32         int ty=uf_find(y);
    33         if(tx!=ty)
    34             root[tx]=ty;
    35     }
    36 
    37     vector<int> findRedundantConnection(vector<vector<int>>& edges) 
    38     {
    39         int k=edges.size();
    40         int kx,ky;
    41         uf_init(k);
    42         for(int i=0;i<k;i++)
    43         {
    44             kx=edges[i][0];
    45             ky=edges[i][1];
    46             if(uf_find(kx)!=uf_find(ky))
    47                 uf_union(kx,ky);
    48             else
    49                 return(edges[i]);
    50         }
    51     }
    52 };
    53 
    54 
    55 int main()
    56 {
    57     Solution sl;
    58     return 0;
    59 }
    View Code

    685. Redundant Connection II = 改成了有向图,复杂了许多......

    不会做嘤嘤嘤

    721. Accounts Merge

    比较裸的并查集。将email重复的两个账户union一下,最后再输出每个集合

     1 class Solution:
     2     def uf_init(self,x):
     3         self.root=[0 for i in range(x+10)]
     4         for i in range(x):
     5             self.root[i]=i
     6 
     7     def uf_find(self, x):
     8         if(x!=self.root[x]):
     9             self.root[x]=self.uf_find(self.root[x])
    10         return self.root[x]
    11 
    12     def uf_union(self, x, y):
    13         tx=self.uf_find(x)
    14         ty=self.uf_find(y)
    15         if(tx!=ty):
    16             self.root[tx]=ty
    17 
    18     def similar(self, acc1, acc2):
    19         res=0
    20         if(acc1[0]!=acc2[0]):
    21             return res
    22         for i in acc1[1:]:
    23             for j in acc2[1:]:
    24                 if(i==j):
    25                     res=1
    26         return res
    27 
    28     def accountsMerge(self, accounts):
    29         """
    30         :type accounts: List[List[str]]
    31         :rtype: List[List[str]]
    32         """
    33         ka=len(accounts)
    34         print(ka)
    35         self.uf_init(ka)
    36         
    37         hsh={}
    38         for i in range(ka):
    39             for j in range(len(accounts[i])-1):
    40                 if(hsh.get(accounts[i][j+1])!=None):
    41                     dx=hsh[accounts[i][j+1]]
    42                     uf_union(dx,i)
    43                 else:
    44                     hsh[accounts[i][j+1]]=i
    45 
    46 
    47         dct=[set() for i in range(ka)]
    48         lbl=["" for i in range(ka)]
    49         for i in range(ka):
    50             ui=self.uf_find(i)
    51             lbl[ui]=accounts[i][0]
    52             for j in range(len(accounts[i])-1):
    53                 dct[ui].add(accounts[i][j+1])
    54 
    55         ans=[]
    56         for i in range(ka):
    57             if(lbl[i]!=""):
    58                 tmp=[]
    59                 for j in dct[i]:
    60                     tmp.append(j)
    61                 tmp.sort()
    62                 tmp=[lbl[i]]+tmp
    63                 ans.append(tmp)
    64 
    65         return ans
    View Code

    注意用hashmap优化掉两重循环的方法,比较常用

    1         for i in range(0,ka):
    2             for j in range(i+1,ka):
    3                 if(self.similar(accounts[i],accounts[j])):
    4                     self.uf_union(i,j)
    优化前
    1         hsh={}
    2         for i in range(ka):
    3             for j in range(len(accounts[i])-1):
    4                 if(hsh.get(accounts[i][j+1])!=None):
    5                     dx=hsh[accounts[i][j+1]]
    6                     uf_union(dx,i)
    7                 else:
    8                     hsh[accounts[i][j+1]]=i
    优化后

    399. Evaluate Division

    一开始想了半天是不是数学题...其实在纸上画画可以发现,这是一个图论题......

    这样就转化成了求图中每对节点最短路问题,这时小学生会选择用Floyd算法,时间复杂度O(N^3)

     1 #define GMAX 0x7f7f7f7f
     2 // initiate double with maxium value:
     3 // https://blog.csdn.net/popoqqq/article/details/38926889
     4 
     5 class Solution {
     6 public:
     7     double graph[1010][1010];
     8 
     9     vector<double> calcEquation(vector<pair<string, string>> equations, 
    10                                 vector<double>& values, 
    11                                 vector<pair<string, string>> queries) 
    12     {
    13         memset(graph,0x7f,sizeof(graph));
    14         cout<<graph[4][3]<<endl;
    15         int kl=values.size(), kq=queries.size();
    16         map<string,int> dict;
    17         int dcnt=0,dx,dy;
    18         for(int i=0;i<kl;i++)
    19         {
    20             if(dict.find(equations[i].first)==dict.end())
    21             {
    22                 dcnt++;
    23                 dict.insert(pair<string, int>(equations[i].first, dcnt));
    24             }
    25             if(dict.find(equations[i].second)==dict.end())
    26             {
    27                 dcnt++;
    28                 dict.insert(pair<string, int>(equations[i].second, dcnt));
    29             }
    30             dx=dict[equations[i].first];
    31             dy=dict[equations[i].second];
    32             graph[dx][dy]=values[i];
    33             graph[dy][dx]=1/values[i];
    34             cout<<dx<<"--"<<dy<<" "<<values[i]<<endl;
    35         }
    36 
    37         for(int i=1;i<=dcnt;i++)
    38             graph[i][i]=1;
    39         for(int k=1;k<=dcnt;k++)
    40             for(int i=1;i<=dcnt;i++)
    41                 for(int j=1;j<=dcnt;j++)
    42                     if(graph[i][k]<GMAX && graph[k][j]<GMAX)
    43                         graph[i][j]=min(graph[i][j],graph[i][k]*graph[k][j]);
    44         
    45         vector<double> ans;
    46         string sx,sy;
    47         for(int i=0;i<kq;i++)
    48         {
    49             sx=queries[i].first;
    50             sy=queries[i].second;
    51             if(dict.find(sx)==dict.end() || dict.find(sy)==dict.end())
    52                 ans.push_back(-1.0);
    53             else
    54             {
    55                 dx=dict[sx];
    56                 dy=dict[sy];
    57                 if(graph[dx][dy]<GMAX)
    58                     ans.push_back(graph[dx][dy]);
    59                 else
    60                     ans.push_back(-1.0);
    61                 cout<<dx<<"__"<<dy<<endl;
    62             }
    63         }
    64 
    65         return ans;
    66     }
    67 };
    View Code

    但大学生们会用并查集来解呢

    balabala

  • 相关阅读:
    使用json-lib进行Java和JSON之间的转换
    PHP实现RabbitMQ消息队列(转)
    PHP错误日志和内存查看(转)
    linux下安装python3(转)
    如何在Linux上设置SSH密码以进行无密码登录(转)
    事务的ACID特性(转)
    PHP之缓存雪崩,及解决方法(转)
    php字符串统计次数的各种方法(转)
    php批量检测和去掉bom头(转)
    go延时队列
  • 原文地址:https://www.cnblogs.com/pdev/p/9536921.html
Copyright © 2011-2022 走看看