基於c語言實現無向圖——鄰接矩陣


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM