问题:给定一幅图,问是否能转换成树。
转换:给定一幅图,问是否存在环(loop)或孤立点。
实现:
首先确保边的个数等于结点个数减一。这样,只要检查有没有环就可以。当边的个数等于结点个数减一时,若存在环,则也一定也存在孤立点,反之,若不存在环,则也一定不存在孤立点。
其次我们检查是否存在环。这里我们另维护了一个二维数组block,block每列记录的是相连的点。
当加入的一组点存在同一列block之中,说明环存在,反之即可加入block中。
一组点加入block有三种情况:
1.block中无任何两点的信息,新开一列存储这两个点。
2.block中只存储过其中一个点,则把另外一个点也加入同一列block。
3.两个点分属block两列,则这组点的加入将这两列点连接了起来,合并这两列。
以下为具体实现代码:
class Solution {
bool BothInBlock(vector<int> edge,vector< vector<int> > block){
int a=edge[0];
int b=edge[1];
for(int i=0;i<block.size();i++){
if(find(block[i].begin(),block[i].end(),a)!=block[i].end()&&find(block[i].begin(),block[i].end(),b)!=block[i].end())
return 1;
}
return 0;
}
void AddToBlock(vector<int> edge,vector< vector<int> >& block){
int a=edge[0];
int b=edge[1];
int count=0;
vector<int>::iterator p1,p2;
int i1=-1;
int i2=-1;
for(int i=0;i<block.size();i++){
if(find(block[i].begin(),block[i].end(),a)!=block[i].end())
i1=i;
else if(find(block[i].begin(),block[i].end(),b)!=block[i].end())
i2=i;
//when two points are in different vectors,merge the two vectors.
if(i1!=-1&&i2!=-1){
block[i1].insert(block[i1].end(),block[i2].begin(),block[i2].end());
block.erase(block.begin()+i2);
return;
}
}
//when neither of the two points has appeared before.
if(i1==-1&&i2==-1){
vector<int> newEdge;
newEdge.push_back(a);
newEdge.push_back(b);
block.push_back(newEdge);
}
//when one point belongs to a block while the other hasn't appeared before.
else{
for(int i=0;i<block.size();i++){
if(find(block[i].begin(),block[i].end(),a)!=block[i].end()){
block[i].push_back(b);
return;
}
if(find(block[i].begin(),block[i].end(),b)!=block[i].end()){
block[i].push_back(a);
return;
}
}
}
}
public:
/**
* @param n an integer
* @param edges a list of undirected edges
* @return true if it's a valid tree, or false
*/
bool validTree(int n, vector< vector<int> >& edges) {
vector< vector<int> >block;
//when some nodes are isolated or when too much edges exists.
if(edges.size()!=n-1)
return 0;
for(int i=0;i<edges.size();i++){
//if two points have been already connected
if(BothInBlock(edges[i],block))
return 0;
else
AddToBlock(edges[i],block);
}
return 1;
}
};