Pentium.Labs

System全家桶:https://zhuanlan.zhihu.com/c_1238468913098731520

导航

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

 

posted on 2018-08-26 12:54  Pentium.Labs  阅读(237)  评论(0编辑  收藏  举报



Pentium.Lab Since 1998