Leetcode684. 冗余连接(C语言)
数据结构-图(并查集):算法与数据结构参考
题目:
在本问题中, 树指的是一个连通且无环的无向图。
输入一个图,该图由一个有着N个节点 (节点值不重复1, 2, …, N) 的树及一条附加的边构成。附加的边的两个顶点包含在1到N中间,这条附加的边不属于树中已存在的边(3<=N<=1000)。
结果图是一个以边组成的二维数组。每一个边的元素是一对[u, v] ,满足 u < v,表示连接顶点u 和v的无向图的边。
返回一条可以删去的边,使得结果图是一个有着N个节点的树。如果有多个答案,则返回二维数组中最后出现的边。答案边 [u, v] 应满足相同的格式 u < v。例:
输入: [[1,2], [2,3], [3,4], [1,4], [1,5]]
输出: [1,4]
解释: 给定的无向图为:
5 - 1 - 2
| |
4 - 3
思路:
并查集。
代码:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int pre[2001]={0};
int find(int root){ //找根节点
int son=root,tmp;
while(root!=pre[root]) root=pre[root]; //当前节点非根节点,就向上找根节点
while(son!=root){ //当前节点到根节点前一个结点都直接连接到根节点(压缩路径)
tmp=pre[son];
pre[son]=root;
son=tmp;
}
return root;
}
void unionSet(int root1,int root2){ //注意union是关键字,不能直接用
int x=find(root1);
int y=find(root2);
if(x!=y) pre[x]=y; //合并根节点
return;
}
int* findRedundantConnection(int** edges, int edgesSize, int* edgesColSize, int* returnSize){
int *ret=(int*)malloc(2*sizeof(int));
for(int i=0;i<edgesSize+1;i++) pre[i]=i;
int x,y;
for(int i=0;i<edgesSize;i++){
x=find(edges[i][0]);
y=find(edges[i][1]);
if(x!=y) unionSet(edges[i][0],edges[i][1]); //不同根,合并i两个节点的根节点
else{ //返回同根最后的边
ret[0]=edges[i][0];
ret[1]=edges[i][1];
}
}
*returnSize=2;
return ret;
}