重连通量的邻接矩阵和邻接表两种形式的求法

邻接矩阵:

#include <cstdio>
#include <cstring>
#include <stack>
using namespace std;
#define min(a,b) a<b?a:b
#define N 105
int dfn[N],low[N],mat[N][N],visit[N],tmpdfn,n;
struct Edge{
    int x,y;
    void print(){
        printf("%d-%d\n",x,y);
    }
    bool cmp(Edge &m){
        return (x==m.x&&y==m.y)||(x==m.y&&y==m.x);
    }
}edge[10005];
stack<Edge> s;
void dfs(int u)
{
    Edge t,tt;
    dfn[u]=low[u]=++tmpdfn,visit[u]=1;
    for(int i=1;i<=n;i++){
        if(mat[u][i]){
            mat[i][u]=0;
            t.x=u,t.y=i;
            s.push(t);
            if(!visit[i]){
                dfs(i);
                low[u]=min(low[u],low[i]);
                if(low[i]>=dfn[u]){
                    //这个while循环没有把最后匹配到的相同边输出,所以最后在pop一次
                    while(!t.cmp(s.top())){
                        tt=s.top();
                        tt.print();
                        s.pop();
                    }
                    tt=s.top();
                    tt.print();
                    s.pop();
                }
            }
            else low[u]=min(low[u],dfn[i]);
        }
    }
}
void init()
{
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(visit,0,sizeof(visit));
    tmpdfn=0;
}
int main()
{
    int a,b,k;
    scanf("%d",&k);
    n=0;
    for(int i=1;i<=k;i++){
        scanf("%d%d",&a,&b);
        mat[a][b]=1,mat[b][a]=1;
        if(a>n) n=a;
        if(b>n) n=b;
    }
    init();
    for(int i=1;i<=n;i++)
        if(!visit[i]) dfs(i);
    return 0;
}

邻接表:

#include <cstdio>
#include <cstring>
#include <stack>
#include <iostream>
using namespace std;
#define N 105
#define min(a,b) a<b?a:b
int visit[N],dfn[N],low[N],first[N],tmpdfn,k,n;

struct Edge{
    int x, y;
    void print(){
        printf("%d-%d\n",x,y);
    }
    bool cmp(Edge &m){
        return (m.x==x&&m.y==y)||(m.y==x&&m.x==y);
    }
};
stack<Edge> s;
struct Path{
    int y,next,vis;
}path[10005];
void add(int x,int y)
{
    path[k].y=y,path[k].next=first[x];
    first[x]=k;
    k++;
}
void init()
{
    memset(visit,0,sizeof(visit));
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(first,-1,sizeof(first));
    k=0,tmpdfn=0;
}
void dfs(int u)
{
    Edge t,tt;
    dfn[u]=low[u]=++tmpdfn,visit[u]=1;
    for(int i=first[u];i!=-1;i=path[i].next){
        if(!path[i].vis){
            t.x=u,t.y=path[i].y;
            s.push(t);
            path[i].vis=1,path[i^1].vis=1;
            if(!visit[path[i].y]){
                dfs(path[i].y);
                low[u]=min(low[u],low[path[i].y]);
                if(low[path[i].y]>=dfn[u]){
                    while(!t.cmp(s.top())){
                        tt=s.top();
                        tt.print();
                        s.pop();
                    }
                    tt=s.top();
                    tt.print();
                    s.pop();
                }
            }
            else low[path[i].y]=min(dfn[u],low[path[i].y]);
        }
    }
}
int main()
{
    int a,b,m;
    scanf("%d%d",&n,&m);
    init();
    for(int i=1;i<=m;i++){
        scanf("%d%d",&a,&b);
        add(a,b);
        add(b,a);
    }

    for(int i=1;i<=n;i++)
        if(!visit[i]) dfs(i);
    return 0;
}

重连通量的邻接矩阵和邻接表两种形式的求法

时间: 2024-08-07 00:17:29

重连通量的邻接矩阵和邻接表两种形式的求法的相关文章

图的存储结构:邻接矩阵(邻接表)&amp;链式前向星

[概念]疏松图&稠密图: 疏松图指,点连接的边不多的图,反之(点连接的边多)则为稠密图. Tips:邻接矩阵与邻接表相比,疏松图多用邻接表,稠密图多用邻接矩阵. 邻接矩阵: 开一个二维数组graph[ ][ ]来记录图中点a与点b之间是否连通,初始化为0(或者-1之类的看情况):如果图中有可忽略的重边(如 只需重边中的最小边或最大边),则保存需要的那条边的边权,但如果有无法忽略的重边,就一定不要用邻接矩阵. int graph[MAXN][MAXN]; void graphInit() { me

PAT1013. Battle Over Cities(邻接矩阵、邻接表分别dfs)

//采用不同的图存储结构结构邻接矩阵.邻接表分别dfs,我想我是寂寞了吧,应该试试并查集,看见可以用并查集的就用dfs,bfs代替......怕了并查集了 //邻接矩阵dfs #include<cstdio>#include<algorithm>using namespace std;const int maxn=1001;int g[maxn][maxn];int n,tmp;bool vis[maxn];void dfs(int v){ vis[v]=true; for(int

无向图的表示:邻接矩阵和邻接表

这里将一个无向图用邻接表和邻接矩阵表示. 输入:顶底个数n,图中的各个边(用两个顶点表示). 输出:这个无线图的邻接矩阵和邻接表,其中邻接表中的链接按元素大小升序排列. 先给出一个例子说明.假设有无向图如下,则其邻接矩阵和邻接表如提示框中所示(其实就是下面程序的输出). 下面是程序的代码: #include <stdio.h> #include <stdlib.h> //图的表示,输入节点个数和边,构造图的邻接矩阵和邻接表 //邻接表中的链表节点 struct vNode{ int

图的邻接矩阵与邻接表

一.如何创建邻接表和邻接矩阵? 如图,根据上图建立一个无向图的邻接矩阵和邻接表~ 输入的数据,第一行为两个整数n,e(0<n<=1000,0<e<=5000),表示有n个点和e条边,接下来的e行,每行包含2个整数,表示每条边所连接的两个点. 然后输出图.(无硬性要求) 输入数据: 5 81 01 21 32 32 43 43 04 0 输出数据(示例): 0->1->3->4->NULL1->0->2->3->NULL2->1-

数据结构基础 之 通过邻接矩阵与邻接表 图 实现

[邻接矩阵] 邻接矩阵,就是一个反应边与边之间联系的二维数组.这个二维数组我们用matrix[numV][numV]表示,其中numV是顶点数. 对于无权图 若顶点Vi和Vj之间有边,则matrix[Vi][Vj]=1;否则matrix[Vi][Vj]=0. 对于有权图 若顶点Vi和Vj之间有边,且权值为weight,则matrix[Vi][Vj]=weight;否则matrix[Vi][Vj]=0或MAXWEIGHT(取最小权值或最大权值). [邻接表] 当图中的边数较少时,用邻接矩阵来实现图

基于邻接矩阵和邻接表的两种方法实现无向图的BFS和DFS

广度优先搜索(Breadth-First-Search)和深度优先搜索(Deep-First-Search)是搜索策略中最经常用到的两种方法,特别常用于图的搜索. BFS的思想: 从一个图的某一个顶点V0出发,首先访问和V0相邻的且未被访问过的顶点V1.V2.--Vn,然后依次访问与V1.V2--Vn相邻且未被访问的顶点.如此继续,找到所要找的顶点或者遍历完整个图.我们采用队列来存储访问过的节点. DFS的思想: 深度优先搜索所遵循的策略就是尽可能"深"的在图中进行搜索,对于图中某一个

图的两种存储(邻接矩阵和邻接表)和两种遍历(DFS和BFS)

图的表示有很多,形式不固定,我暂时先记录我已经懂了的,能写的两种即大多数人应该都知道的邻接矩阵和邻接表. 邻接矩阵: 这里的邻接矩阵和离散数学说的有一点不同,至少有向图的邻接矩阵不同(离散书上的有向图的邻接矩阵求法到是有点像求任意两点的最短路径的Floyd算法) 以上都是(我现有知识认为的)废话: 重点 : G : 表示图: Nv:表示图的点数: Ne:表示图的边数: 邻接矩阵 即是一个 Nv * Nv 的矩阵,矩阵是用来储存  权值的(如果是带权图且有边的话),如果是无权图的的话,如果两顶点有

图(网)的存储结构(数组存储表示即邻接矩阵、邻接表)

图(Graph)是一种非线性结构 图的特点(多对多),顶点之间的关系是任意的,图中任意两个顶点之间都可能相关,顶点的前驱和后继个数无限制. 图:数据元素间存在多对多关系的数据结构,加上一组基本操作构成的抽象数据类型. 图的基本术语 顶点:图中的数据元素. 弧:若 <v, w>∈VR,则 <v, w> 表示从 v 到 w 的一条弧,且称 v 为弧尾,称 w 为弧头,此时的图称为有向图. G1 = (V1, A1)          V1 = {v1, v2, v3, v4} A1 =

【裸MST:prim+邻接矩阵 / Kruskal+邻接表】hdu 1233 还是畅通工程

Source : hdu 1233 还是畅通工程 http://acm.hdu.edu.cn/showproblem.php?pid=1233 Problem Description 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小.请计算最小的公路总长度. Input 测试输入包含若干测试用例.每个测试用例的第1行给出村庄