基于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