一、题目
二、代码
class Solution
{
public:
//入度是有意义的 出度是没有意义的 因为一个父节点就会有很多的出度
//多出的一条边 对于其指向的节点 会有两种情况 双入度或者形成环
//对于双入度 看删除哪一条边仍能构成树
//对于环 查看是哪一条边构成了环
//并查集部分
//并查集 基本步骤 初始化 并 查 判断
static const int n=1001;
int father[1001];
//初始化
void init()
{
for(int i=0;i<n;i++) father[i]=i;
}
//查找
int find(int u)
{
return u==father[u] ? u:find(father[u]);
}
//合并
void join(int u ,int v)
{
u=find(u);
v=find(v);
if(u==v) return;
else
{
father[v]=u;
}
}
//判断是否具有相同的根节点
bool same(int u , int v)
{
u=find(u);
v=find(v);
return u==v;
}
vector<int> circle_edge(vector<vector<int>>& edges)
{
int i,j;
init();
for(i=0;i<edges.size();i++)
{
if(same(edges[i][0],edges[i][1])) return edges[i];
else
{
join(edges[i][0],edges[i][1]);
}
}
return {};
}
bool two_input_edge(vector<vector<int>>& edges, int delete_edge)
{
int i,j;
init();
for(i=0;i<edges.size();i++)
{
if(i==delete_edge) continue;
else
{
if(same(edges[i][0],edges[i][1])) return false; //有环 说明删错了
else
{
join(edges[i][0],edges[i][1]);
}
}
}
return true;
}
vector<int> findRedundantDirectedConnection(vector<vector<int>>& edges)
{
int i,j;
//统计入度
//入度为2 删除仍未树
//没有入度为2的节点 寻找使之成为环的节点
int in_degree[n]={0,};
for(i=0;i<edges.size();i++) in_degree[edges[i][1]]++;
vector<int> vec_of_two;
for(i=edges.size()-1;i>=0;i--) //只会有一个双入度 但是[2,3] [1,3] vector仍会有两个
{
if(in_degree[edges[i][1]]==2) vec_of_two.push_back(i);
}
//只有有一个入度为2 但要判断是两条边的哪一条
// std::cout<<" size "<<vec_of_two.size() <<std::endl;
if(vec_of_two.size()>0)
{
if(two_input_edge(edges,vec_of_two[0]))
{
return edges[vec_of_two[0]];
}
else
{
return edges[vec_of_two[1]];
}
}
//当没有入度为2的节点时 找环
return circle_edge(edges);
}
};