/* * @lc app=leetcode.cn id=684 lang=c * * [684] 冗余连接 * * https://leetcode-cn.com/problems/redundant-connection/description/ * * algorithms * Medium (54.97%) * Likes: 75 * Dislikes: 0 * Total Accepted: 5.7K * Total Submissions: 10.3K * Testcase Example: '[[1,2],[1,3],[2,3]]' * * 在本问题中, 树指的是一个连通且无环的无向图。 * * 输入一个图,该图由一个有着N个节点 (节点值不重复1, 2, ..., N) * 的树及一条附加的边构成。附加的边的两个顶点包含在1到N中间,这条附加的边不属于树中已存在的边。 * * 结果图是一个以边组成的二维数组。每一个边的元素是一对[u, v] ,满足 u < v,表示连接顶点u 和v的无向图的边。 * * 返回一条可以删去的边,使得结果图是一个有着N个节点的树。如果有多个答案,则返回二维数组中最后出现的边。答案边 [u, v] 应满足相同的格式 u < * v。 * * 示例 1: * * 输入: [[1,2], [1,3], [2,3]] * 输出: [2,3] * 解释: 给定的无向图为: * 1 * / \ * 2 - 3 * * * 示例 2: * * 输入: [[1,2], [2,3], [3,4], [1,4], [1,5]] * 输出: [1,4] * 解释: 给定的无向图为: * 5 - 1 - 2 * | | * 4 - 3 * * * 注意: * * * 输入的二维数组大小在 3 到 1000。 * 二维数组中的整数在1到N之间,其中N是输入数组的大小。 * * * 更新(2017-09-26): * 我们已经重新检查了问题描述及测试用例,明确图是无向 图。对于有向图详见冗余连接II。对于造成任何不便,我们深感歉意。 * */ /*************************************************************** * 基于c语言实现无向图 * 图的表示方法: 邻接矩阵 (比较耗费内存,且需要遍历检查是否有路径,比较耗时) * 无向图算法:深度优先搜索 + 环路检测算法 + 环路路径输出 * 解题思路:首先,利用深度优先搜索算法检测图的连通性,记录路径; * 同时检测是否有环路,输出环路路径; * 最后循环检测环路中的路径的排序,记录排序最大的 * 注意:记录环路路径的时候,避免重复进入 ****************************************************************/ #include <iostream> using namespace std; // @lc code=start typedef struct { int v; int e; bool **adj; }GraphMatrix; GraphMatrix* GraphInit(int v) { GraphMatrix* s; int i = 0; s = (GraphMatrix*)malloc(sizeof(GraphMatrix)); if (s == NULL) { return NULL; } s->v = v; s->adj = (bool **)malloc(v * sizeof(bool *)); for (i = 0; i < v; i++) { s->adj[i] = (bool *)malloc(v * sizeof(bool)); memset(s->adj[i],false, v * sizeof(bool)); } return s; } void GraphFree(GraphMatrix* s) { if (s != NULL) { int i = 0; int v = s->v; for (i = 0; i < v; i++) { free(s->adj[i]); } free(s->adj); free(s); } } void GraphAddEdge(GraphMatrix* s, int** edges, int edgesSize) { int i = 0; s->e = edgesSize; for (i = 0; i < edgesSize; i++) { s->adj[edges[i][0]][edges[i][1]] = true; s->adj[edges[i][1]][edges[i][0]] = true; } } void GraphCycleDetect(GraphMatrix* s, int v, int u, bool* mark, int* edgeTo, int* hasCycle) { int i = 0; int x = 0; mark[v] = true; for (i = 0; i < s->v; i++) { if (s->adj[v][i]) { // edge if (mark[i]) { if (i != u) { // hascycle if (hasCycle[0] < 0) { // 避免重复进入 int count = 0; for (x = v; x != i; x = edgeTo[x]) { hasCycle[count] = x; count++; } hasCycle[count++] = i; hasCycle[count] = v; } } } else { edgeTo[i] = v; GraphCycleDetect(s,i,v,mark,edgeTo,hasCycle); } } } } /** * Note: The returned array must be malloced, assume caller calls free(). */ int* findRedundantConnection(int** edges, int edgesSize, int* edgesColSize, int* returnSize) { int* result = NULL; bool* mark = NULL; int* edgeTo = NULL; GraphMatrix* s = NULL; int *cycle = NULL; int i = 0; int j; int large, small; int order = -1; *returnSize = 2; result = (int*)malloc(2 * sizeof(int)); mark = (bool*)malloc((edgesSize + 1) * sizeof(bool)); memset(mark,false, (edgesSize + 1) * sizeof(bool)); edgeTo = (int*)malloc((edgesSize + 1) * sizeof(int)); memset(edgeTo, 0, (edgesSize + 1) * sizeof(int)); cycle = (int*)malloc((edgesSize + 1) * sizeof(int)); memset(cycle, -1, (edgesSize + 1) * sizeof(int)); s = GraphInit(edgesSize + 1); GraphAddEdge(s, edges, edgesSize); GraphCycleDetect(s, edges[0][0], edges[0][0], mark, edgeTo, cycle); while (cycle[i + 1] >= 0) { if (cycle[i + 1] > cycle[i]) { large = cycle[i + 1]; small = cycle[i]; } else { small = cycle[i + 1]; large = cycle[i]; } for (j = 0; j < edgesSize; j++) { if (large == edges[j][1] && small == edges[j][0]) { if (j > order) { result[0] = edges[j][0]; result[1] = edges[j][1]; order = j; } break; } } i++; if (i == edgesSize) { // detect 数据完毕 break; } } GraphFree(s); // free free(mark); free(edgeTo); free(cycle); return result; } // @lc code=end #define size 3 int main_LeetCode_684() { int edges[size][2] = { {1,2},{1,3},{2,3}}; //int edges[size][2] = { { 1,2 },{ 2,3 },{ 3,4 },{ 1,4 },{ 1,5 } }; int** data = NULL; data = (int**)malloc(size * sizeof(int*)); for (int i = 0; i < size; i++) { data[i] = &(edges[i][0]); } int edgesColSize[size]; int returnSize; findRedundantConnection(data, size, edgesColSize, &returnSize); return 0; }