ACM学习-图双连通子图

// ACM学习-割点和桥.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include<iostream>

#include<queue>

#include<vector>

#include<algorithm>

using namespace std;

const int v = 13;

int edge[v][v] = {

{ 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0 },

{ 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 },

{ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },

{ 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },

{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },

{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },

{ 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0 },

{ 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },

{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 },

{ 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 },

{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1 },

{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }

};

bool vis[v] = { false };

char t[] = { ‘A‘, ‘B‘, ‘C‘, ‘D‘, ‘E‘, ‘F‘, ‘G‘, ‘H‘,

‘I‘, ‘J‘, ‘K‘, ‘L‘, ‘M‘ };

//queue<int> q;

//判断i点到j点是否有两条路径

bool is_can_shuang_lian_tong(int i, int j){

for (int i = 0; i<v; i++){

vis[i] = false;

}

queue<int> q;

q.push(i);

vis[i] = true;

int count = 0;

while (q.size() > 0){

int k = q.front();

q.pop();

if (edge[k][j]){

count++;

vis[j] = true;

if (count == 2)

return true;

}

for (int i = 0; i < v; i++){

if (edge[k][i] && !vis[i])

{

vis[i] = true;

q.push(i);

}

}

}

return false;

}

void print(int i)

{

cout << t[i] << ends;

}

void bian_zi_tu(){//广度优先遍历

queue<int> q;

vector<int> vnum;

int yy[v][v];//这个变量可以去除,没用

memcpy(yy, edge, v*v * sizeof(int));

for (int i = 0; i<v; i++){

vis[i] = false;

}

for (int i = 0; i<v; i++){

if (!vis[i])

{

vis[i] = true;

vnum.clear();

q.push(i);

vnum.push_back(i);

while (q.size() > 0){

int k = q.front();

q.pop();

for (int i = 0; i < v; i++){

if (yy[k][i]&&!vis[i])

{

//yy[k][i] = 0;

//yy[i][k] = 0;

vis[i] = true;

q.push(i);

vnum.push_back(i);

}

}

}//while

for_each(vnum.begin(),vnum.end(),print);

cout << endl;

}

}

}

//得到一个图中是否有双连通子图

void get_shuang_lian_tong(){

bool isContinue = true;

while (isContinue){

int count = 0;

int index = 0;

isContinue = false;//由于删除了节点关系,可能要再删一次

for (int i = 0; i < v; i++){//如果某个节点只有一个节点跟它相连,则删除它与连着的那个节点的关系

count = 0;

for (int j = 0; j < v; j++){

if (edge[i][j]){

++count;

index = j;

}

}

if (count ==1)

{

isContinue = true;

edge[i][index] = 0;

edge[index][i] = 0;

}

}

}

for (int i = 0; i < v; i++){

for (int j = 0; j < v; j++){

if (edge[i][j]){

if (!is_can_shuang_lian_tong( i,j))//判断i与j是否有两条路径

{//如果没有删除他们的关系

edge[i][j] = 0;

edge[j][i] = 0;

}

}

}

}

}

int _tmain(int argc, _TCHAR* argv[])

{

get_shuang_lian_tong();

/*for (int i = 0; i < v; i++){

for (int j = 0; j < v; j++){

if (edge[i][j])

{

cout << t[i] << "和" << t[j] << "连着" << endl;

}

}

}*/

bian_zi_tu();

return 0;

}

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

时间: 2024-12-24 07:20:08

ACM学习-图双连通子图的相关文章

poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&amp;&amp;缩点】

Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10141   Accepted: 5031 Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the r

求水洼的问题(或者是说求图中连通子图的个数)----深度优先算法

遇到这个题的时候,不太容易快速的想到思路:可能会比较容易想到使用递归的思想:但是具体怎么写呢?其实这个题就相当于是图论中的求连通图,很容易应该想到的是深度优先搜索或者是广度优先搜索:我们就用深度优先算法来求这个题目:直接求有几个区域不好求,那么我们换个思路来求,这种题就是这样,直接求不好求,但是当我们转换一下思路之后就豁然开朗: 我们遍历所有的点,当遇到有水的点时,就将它周围的(八个方向)所有的水点都消除:所以在主遍历for循环中遇到几个水点就是有几个水洼: /*****************

双连通问题

一些定义: 割点集合(割集):在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个连通块,就称这个点集为割点集合. 点连通度:最小割点集合中的顶点数. 割边集合:如果有一个边集合,删除这个边集合以后,原图变成多个连通块,就称这个点集为割边集合. 边连通度:最小割边集合中的边数. 点双连通:如果一个无向连通图的点连通度大于1,则称该图是点双连通的,简称双连通或重连通.割点:一个图有割点,当且仅当这个图的点连通度为1,则割点集合的唯一元素被称为

poj3352Road Construction 边双连通+伪缩点

/* 对于边双连通分支,求法更为简单.只需在求出所有的桥以后,把桥边删除,原图变成了多个连通块,则每个连通块就是一个边双连通分支.桥不属于任何 一个边双连通分支,其余的边和每个顶点都属于且只属于一个边双连通分支. 一个有桥的连通图,如何把它通过加边变成边双连通图?方法为首先求出所有的桥, 然后删除这些桥边,剩下的每个连通块都是一个双连通子图.把每个双连通子图收缩为一个顶点, 再把桥边加回来,最后的这个图一定是一棵树,边连通度为1. 统计出树中度为1的节点的个数,即为叶节点的个数,记为leaf.则

【连通图|边双连通+缩点】POJ-3177 Redundant Paths

Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K       Description In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1..F) to another field, Bessie and the rest of the herd are forced to cross near the T

图的连通性问题的小结 (双连通、2-SAT)

图的连通性问题包括: 1.强连通分量. 2.最小点基和最小权点基. 3.双连通. 4.全局最小割. 5.2-SAT 一.强连通分量 强连通分量很少单独出题,一般都是把求强连通分量作为缩点工具. 有三种算法: 1.Kosaraju算法.对原图和反图分别进行一次深度优先搜索. 2.Tarjan算法.用了时间戳. 3.Garbow算法.与Tarjan算法是同一思想,但更精妙. 三种算法的模版我已经贴过了  http://www.cnblogs.com/Potato-lover/p/3956604.ht

Uva 10765 点双连通求删任意点后剩下图中的连通分量数

题目挂在wustoj上,不知道什么原因不能粘贴链接.. 第一题题号为1314..这题是智力题...换成7的阶乘就可以了.. 代码如下. #include<cstdio> int main() { printf("...............................................................................................\n"); printf("..#................

图之强连通、强连通图、强连通分量 Tarjan算法

强连通分量 简介 在阅读下列内容之前,请务必了解图论基础部分. 强连通的定义是:有向图 G 强连通是指,G 中任意两个结点连通. 强连通分量(Strongly Connected Components,SCC)的定义是:极大的强连通子图. 这里想要介绍的是如何来求强连通分量. Tarjan 算法 Robert E. Tarjan (1948~) 美国人. Tarjan 发明了很多算法结构.光 Tarjan 算法就有很多,比如求各种联通分量的 Tarjan 算法,求 LCA(Lowest Comm

割点、桥模板以及点双连通、边双连通

一.概念 概念: 1.桥: 如果在图G中删去一条边e后,图G的连通分支数增加,即W(G-e)>W(G),则称边u为G的桥,又称割边或关节边. 2.割点:如果在图G中删去一个结点u后,图G的连通分枝数增加,即W(G-u)>W(G),则称结点u为G的割点,又称关节点. 3.点双连通分量:不含割点的连通子图 4.边双连通分量:不含割边的连通子图 性质: 1.边双连通分量中,任意两点都在某个边环中.(任意两点不一定在点环中) 2.点双连通分量中,任意两点都在某个点环中. 3.点双连通分量不一定是边双连