/* * @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; }