赞
踩
思路:DFS(连通块)
其实一开始的时候,并不知道这道题的精髓在哪,总想着,啊?这怎么用图论的思想做啊?
细细思考之后,这道题还是比较有意思的,需要有一定的数据结构基础。
这里让我们求最少连接的操作次数。我们其实可以把这些点统统看成是连通块。
例如第一个例子,0,1,2是不是连在一块了?3是不是独立成一块?也就是说,这个例子里面,有两个连通块。我们需要用几条线来连接?我们发现,只需要一条。也就说,2个连通块需要一条来连接,这样全部点都可以访问;如果是3个连通块呢?其实你已经能推出来了,就是2条。
其实这就跟树一样,n个顶点,至少需要n-1边才能成树(树也是图的一种)。这里就运用了这样的数据结构的基础知识。
好了,我们的任务其实就很明确了,找出有多少块连通块;然后,我们需要统计总共给了我们多少条线;最后,我们需要判断连通这些点的最小线数,然后判断一下题目中给我们的线够不够用。
第一个问题很好解决,dfs遍历,然后用一个全局变量统计就行,不要忘记每次dfs的时候需要更新这个变量;
第二个问题,极其的简单,就是connections的二维数组大小。
第三个问题,我们需要着重注意一下细节,首先,我们需要知道一个连通块最少需要多少条线,其实就是上面的知识点,n个顶点的话n-1个就够了,就能至少形成一个连通块。这样的话,我们其实就是重新统计了一遍每个连通块所用的条数,然后相加到sum中,判断总条数-sum,就是我们能够最大限度用的线了。如果说,我们剩下的线足够我们连通这几个连通块,那么就取能够连通这几个连通块的最小条数,而不取剩下的条数;否则,就不能连接上。
注意:你需要额外定义一个二维数组存储各顶点的联通关系。
上代码:
- class Solution {
- public:
- int counts=0;
- void dfs(int u,vector<vector<int>>&s,vector<bool>&st){
- for(int i=0;i<s[u].size();i++){
- int tmp=s[u][i];
- if(!st[tmp]){
- st[tmp]=true;
- counts++;
- dfs(tmp,s,st);
- }
- }
- }
- int makeConnected(int n, vector<vector<int>>& connections) {
- int res=0;
- vector<vector<int>>s(n);
- vector<bool>st(n,false);
- vector<int>ans;
- for(int i=0;i<connections.size();i++){
- int x=connections[i][0];
- int y=connections[i][1];
- s[x].emplace_back(y);
- s[y].emplace_back(x);
- }
- for(int i=0;i<n;i++){
- if(!st[i]){
- st[i]=1;
- res++;
- dfs(i,s,st);
- }
- ans.push_back(counts);
- counts=0;
- }
- int sum=0;
- for(int i=0;i<ans.size();i++){
- sum+=ans[i];
- }
- if(connections.size()>=sum)
- return connections.size()-sum>=res-1?res-1:-1;
- else
- return -1;
- }
- };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。