求割点(邻接表无向图)C~

原创 2017年08月13日 09:54:23

上一篇 : 图割点(邻接矩阵)

邻接表 : O(N+M)

邻接矩阵 : O(N^2)

核心代码 : 

void dfs(int cur, int father, Graph g, Info* info)
	{
		info->index++;
		info->num[cur] = info->index;
		info->low[cur] = info->index;
		info->child = 0;//记录每个顶点孩子数量 
		ENode *node;
		node = g.vex[cur].first_edge;
		while(node != NULL){ //访问 每个 临接点 
			if(info->num[node->ivex] == 0){//当前顶点未访问
				info->child++;//当前顶点孩子数加1
				dfs(node->ivex, cur, g, info);//
				info->low[cur] = min(info->low[cur], info->low[node->ivex]);
				if(info->root != cur && info->low[node->ivex] >= info->num[cur] )
					{
						info->flag[cur] = 1;
						info->cnt++;
					}
				if(info->root == cur && info->child == 2)
					{
						info->flag[cur] = 1;
						info->cnt++;	
					}	
			}
			else if(node->ivex != father){
				info->low[cur] = min(info->low[cur], info->num[node->ivex]);
			}
			node = node->next_edge;
		}
		return ;			
	}

完整实现 : 

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define MAXVEX 100 
typedef char VertexType;  
typedef int WeightType;  
typedef struct ENode {  
    int ivex;//顶点 索引    
    WeightType weight;  
    struct ENode* next_edge;  
}ENode;  
typedef struct Info{// 记录  
	int index;
	int root;
	int child;
	int num[MAXVEX];//当前顶点的时间戳 
	int low[MAXVEX];//能访问到的最早顶点的时间戳 
	int flag[MAXVEX];
	int cnt;
}Info;  
typedef struct VNode {  
    VertexType data; // 顶点 信息    
    ENode* first_edge;  
}VNode;  
  
typedef struct Graph {  
    VNode vex[MAXVEX];  
    int vex_num, edge_num;  
}Graph;  

int index;
char read_char()  
{  
    char ch;  
    do {  
        ch = getchar();  
    } while (!isalpha(ch));  
    return ch;  
}  
  
int get_pos(Graph g, char ch)  
{  
    int i;  
    for (i = 0; i < g.vex_num; i++) {  
        if (ch == g.vex[i].data)  
            return i;  
    }  
  
    return -1;  
}  
  
void link_last(ENode* list, ENode *last)  
{  
    ENode* p;  
    p = list;  
    while (p->next_edge != NULL) {  
        p = p->next_edge;  
    }  
    p->next_edge = last;  
}  

void create_graph(Graph *g)  
{  
    int i, w;  
    printf("请输入顶点数和边数:\n");  
    scanf("%d%d", &g->vex_num, &g->edge_num);  
    printf("请输入顶点信息:\n");  
    for (i = 0; i < g->vex_num; i++) {  
        g->vex[i].first_edge = NULL;  
        g->vex[i].data = read_char();  
    }  
    printf("请输入边 :\n");  
    for (i = 0; i < g->edge_num; i++) {  
        int p1, p2;  
        char c1, c2;  
        c1 = read_char();  
        c2 = read_char();  
    //    scanf("%d", &w);  
        p1 = get_pos(*g, c1);  
        p2 = get_pos(*g, c2);  
        ENode* node1, *node2;  
        node1 = (ENode*)malloc(sizeof(ENode));  
        if (node1 == NULL) {  
            printf("error");  
            return;  
        }  
        node1->next_edge = NULL;  
        node1->ivex = p2;    
        if (g->vex[p1].first_edge == NULL)  
            g->vex[p1].first_edge = node1;  
        else  
            link_last(g->vex[p1].first_edge, node1);
		node2 = (ENode *)malloc(sizeof(ENode));	  
		node2->next_edge = NULL;
		node2->ivex = p1;
        if(g->vex[p2].first_edge == NULL)
			g->vex[p2].first_edge = node2; 
		else
			link_last(g->vex[p2].first_edge, node2);	   
    }  
} 

int min(int a, int b)
	{
		return a < b ? a : b;
	}
// 求割点核心	
void dfs(int cur, int father, Graph g, Info* info)
	{
		info->index++;
		info->num[cur] = info->index;
		info->low[cur] = info->index;
		info->child = 0;//记录每个顶点孩子数量 
		ENode *node;
		node = g.vex[cur].first_edge;
		while(node != NULL){ //访问 每个 临接点 
			if(info->num[node->ivex] == 0){
				info->child++;
				dfs(node->ivex, cur, g, info);
				info->low[cur] = min(info->low[cur], info->low[node->ivex]);
				if(info->root != cur && info->low[node->ivex] >= info->num[cur] )
					{
						info->flag[cur] = 1;
						info->cnt++;
					}
				if(info->root == cur && info->child == 2)
					{
						info->flag[cur] = 1;
						info->cnt++;	
					}	
			}
			else if(node->ivex != father){
				info->low[cur] = min(info->low[cur], info->num[node->ivex]);
			}
			node = node->next_edge;
		}
		return ;			
	}
	
int main()
	{
		Graph g;
		create_graph(&g);
		Info info;
		info.index = 0;
		info.root = 0;
		int i;
		for(int i = 0; i < g.vex_num; i++ ){
			info.num[i] = 0;// 这个必须初始化 为 0 表示未访问 
			info.cnt = 0;
		}
		
		dfs(0, 0, g, &info);
		if(info.cnt == 0){
			printf("\n该图不存在割点");
			return 0;
		}
		printf("\n此图有%d个割点 : ",info.cnt);
		for(i = 0; i < g.vex_num; i++ ){
			if(info.flag[i] == 1)
				printf("%c ", g.vex[i].data);
		}
	
		return 0;	
	} 


版权声明:本文为博主原创文章,未经博主允许不得转载。

计算无向连通图的割点和割边

本总结是是个人为防止遗忘而作,不得转载和商用。 题目          给定某无向连通图G,若删除某节点X和已经与X相邻接的所有边时,图G变成非连通图,则节点X称为图G的割点。         ...
  • xueyingxue001
  • xueyingxue001
  • 2016年10月27日 17:22
  • 458

Tarjan算法求解一个无向图中的割点和桥问题

基本概念割点:Articulation Point 在无向连通图中,删除一个顶点v及其相连的边后,原图从一个连通分量变成了两个或多个连通分量,则称顶点v为割点,同时也称关节点(Articulatio...
  • starstar1992
  • starstar1992
  • 2016年10月27日 13:29
  • 1545

求无向图的割点和桥

/** * 求 无向图的割点和桥 * 可以找出割点和桥,求删掉每个点后增加的连通块。 * 需要注意重边的处理,可以先用矩阵存,再转邻接表,或者进行判重 * 调用solve输出割点数,全局变量b...
  • u013573047
  • u013573047
  • 2015年02月27日 10:27
  • 1347

tarjan算法--求无向图的割点和桥

一.基本概念     1.桥:是存在于无向图中的这样的一条边,如果去掉这一条边,那么整张无向图会分为两部分,这样的一条边称为桥无向连通图中,如果删除某边后,图变成不连通,则称该边为桥。  ...
  • Ezereal
  • Ezereal
  • 2016年10月11日 22:30
  • 451

c语言实现无向图的邻接表储存

图有一种邻接表储存结构,这里以无向图为例,输入图的参数,构造并输出图的邻接表。 #include #include #define MAX_VERTEX_NUM 100 typedef struct...
  • L_BestCoder
  • L_BestCoder
  • 2016年03月02日 21:46
  • 5142

无向连通图的割点、桥

无向连通图的割点、桥 泳裤王子原创,转载请注明出处 http://blog.csdn.net/tclh123/article/details/6705392 预备知识:        割点集合 ...
  • tclh123
  • tclh123
  • 2011年08月21日 00:40
  • 7241

BZOJ_P1123 [POI2008]BLO(无向图割点)

BZOJ传送门Time Limit: 10 Sec Memory Limit: 162 MB Submit: 810 Solved: 344 [Submit][Status][Discuss]...
  • qq_18455665
  • qq_18455665
  • 2016年03月24日 19:59
  • 488

无向图求割点

using namespace std; const int MAXE = 300010; const int MAXP = 1010; struct N { int v,next; }e...
  • u012161037
  • u012161037
  • 2015年05月15日 15:04
  • 590

无重边连通无向图求割点和桥

一.割点和桥  无向连通图中,如果删除某点后,图变 成不连通,则称该点为割点。    无向连通图中,如果删除某边后,图变 成不连通,则称该边为桥。 所以说啊,割点和桥这个概念的应该范围应该只是在...
  • u013555159
  • u013555159
  • 2016年09月03日 21:01
  • 479

用Tarjan算法求无向连通图割点&&割边

/** 割点割边挺好理解的,割点就是一个无向连通图,把其中一个点 挖掉剩下的图不连通,割边就是把一条边砍掉不连通 比如:有一个通信网络,要求一颗炸弹,把这个通信网络搞得不连通...
  • zcube
  • zcube
  • 2015年09月05日 10:11
  • 2431
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:求割点(邻接表无向图)C~
举报原因:
原因补充:

(最多只允许输入30个字)