码迷,mamicode.com
首页 > 其他好文 > 详细

【编程题目】求一个有向连通图的割点,割点的定义是,如果除去此节点和与其相关的边, 有向图不再连通

时间:2014-09-25 10:47:48      阅读:411      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   io   ar   strong   for   div   sp   

39.(树、图、算法)
(2).
求一个有向连通图的割点,割点的定义是,如果除去此节点和与其相关的边,
有向图不再连通,描述算法。

 

思路:这里有个问题,对于图的连通性,我默认它要求强连通。采用了最简单的办法,即每次删掉一条边,判断图还是否连通。若变得不连通了就认为此点是割点。

连通性的判断也采用了直觉上简单的方法,就是对每一个点判断是否有向内指向它的边和它向外指向的边。(question:如此直观的方法是否会有错呢?)

/*
39.(树、图、算法)
(2).
求一个有向连通图的割点,割点的定义是,如果除去此节点和与其相关的边,
有向图不再连通,描述算法。
*/

#include <stdio.h>

#define MAX_VERTEX_NUM 20
#define INFINITY 10000

typedef struct ArcCell{
    int adj;
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedef struct MGraph{
    int vexs[MAX_VERTEX_NUM];
    AdjMatrix arcs;
    int vexnum, arcnum;
}MGraph;

//定位顶点
int LocateVex(MGraph G, int v)
{
    for(int i = 0; i < G.vexnum; i++)
    {
        if(G.vexs[i] == v)
            return i;
    }
    return -1; //means error
}
void CreateDN(MGraph &G) //生成有向图
{
    printf("Input the vexnum:");
    scanf("%d",&G.vexnum);
    printf("Input the arcnum:");
    scanf("%d", &G.arcnum);

    for(int i = 0; i < G.vexnum; i++)
    {
        printf("Input the %d vex:", i);
        scanf("%d", &G.vexs[i]);
    }

    for(int i = 0; i < G.vexnum; i++)
        for(int j = 0; j < G.vexnum; j++)
            G.arcs[i][j].adj = INFINITY;

    for(int k = 0; k < G.arcnum; k++)
    {
        int v1, v2, w;
        printf("input the arcs vex and weight:");
        scanf("%d %d %d", &v1, &v2, &w);
        int i = LocateVex(G, v1);
        int j = LocateVex(G, v2);
        G.arcs[i][j].adj = w;
    }
}

//有向图是否强连通
bool isConnected(MGraph G)
{
    bool connected = true;
    for(int i = 0; i < G.vexnum; i++)
    {
        bool haveConnectedIn = false;
        bool haveConnectedOut = false;
        for(int j = 0; j < G.vexnum; j++)
        {
            if(G.arcs[i][j].adj < INFINITY)
                haveConnectedOut = true;
            if(G.arcs[j][i].adj < INFINITY)
                haveConnectedIn = true;
        }

        if(haveConnectedOut != true || haveConnectedIn != true)
        {
            connected = false;
            break;
        }
    }

    return connected;
}

//得到有向图G去掉一个顶点和其相邻边后的图
MGraph deleteOneVex(MGraph G, int vex)
{
    MGraph DG;
    DG.vexnum = G.vexnum - 1;
    int j = 0;
    for(int i = 0; i < G.vexnum; i++)
    {
        if(i != vex)
        {
            DG.vexs[j++] = G.vexs[i]; 
        }
    }

    DG.arcnum = 0;
    for(int i = 0; i < G.vexnum; i++)
        for(int j = 0; j < G.vexnum; j++)
            if(i != vex && j != vex)
            {
                int v = (i > vex) ? i - 1 : i;
                int u = (j > vex) ? j - 1 : j;
                DG.arcs[v][u].adj = G.arcs[i][j].adj;
                DG.arcnum++;
            }

    return DG;
}

//查找图的割
void GetGutSet(MGraph G)
{
    bool isconnect = isConnected(G);
    if(isconnect == false)
    {
        printf("the Graph is not connected.\n");
        return;
    }

    int n = 0;
    if(G.vexnum < 1)
    {
        printf("no vex");
    }
    else if(G.vexnum == 1)
    {
        printf("cut is %d\n", G.vexs[0]);
    }
    else
    {
        for(int i = 0 ; i < G.vexnum; i++)
        {
            MGraph DG = deleteOneVex(G, i);
            bool isconnect = isConnected(DG);
            if(isconnect == false)
            {
                printf("The %d cut vex is %d\n", n, G.vexs[i]);
            }
        }
    }
}

int main()
{
    MGraph G;
    CreateDN(G);
    GetGutSet(G);

    return 0;
}

 

网上看到有专门的算法,还在学习。

【编程题目】求一个有向连通图的割点,割点的定义是,如果除去此节点和与其相关的边, 有向图不再连通

标签:style   blog   color   io   ar   strong   for   div   sp   

原文地址:http://www.cnblogs.com/dplearning/p/3992097.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!