zoukankan      html  css  js  c++  java
  • 图的遍历——A1013Battle over cities(25) 求需要添加多少条边才能构成连通图转化为找连通分量(可由DFS 和 并查集来找连通分量)

    #include <bits/stdc++.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <queue>
    using namespace std;
    const int N = 1111;
    vector<int> G[N];//邻接表
    bool vis[N];//标记顶点i是否被访问
    int currentPoint;//当前需要删除的顶点编号
    void dfs(int v){
        if(v == currentPoint) return;
        vis[v] = true;
        for(int i = 0;i<G[v].size();++i){
            if(vis[G[v][i]] == false){
                dfs(G[v][i]);
            }
        }
    
    }
    
    int n,m,k;
    int main(){
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<m;++i){
            int a,b;
            scanf("%d%d",&a,&b);
            G[a].push_back(b);
            G[b].push_back(a);
        }
        for(int query = 0;query < k;++query){
            scanf("%d",&currentPoint);
            memset(vis,false,sizeof(vis));//初始化vis数组为false
            int block = 0;//联通块个数,初始化为0
            for(int i=1;i<=n;++i){
                if(i != currentPoint && vis[i] == false){//如果未被删除且未被访问
                    dfs(i);
                    block++;
                }
            }
            printf("%d
    ",block - 1);//输出联通块个数-1,表示需要增加的边
    
        }
        system("pause");
        return 0;
    }

    并查集

    #include <bits/stdc++.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <queue>
    using namespace std;
    const int N = 1111;
    vector<int> G[N];//邻接表
    int father[N];
    bool vis[N];
    int findFather(int x){
        int a = x;
        while(x != father[x]){
            x = father[x];
        }
        //路径压缩,为了避免超时
        while(a != father[a]){
            int z = a;
            a = father[a];
            father[z] = x;
        }
        return x;
    }
    void Union(int a,int b){
        int faA = findFather(a);
        int faB = findFather(b);
        if(faA != faB){
            father[faA] = faB;
        }
    }
    void init(){
        for(int i = 1;i<N;++i){
            father[i] = i;
            vis[i] = false;
        }
    }
    int n,m,k;
    int main(){
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<m;++i){
            int a,b;
            scanf("%d%d",&a,&b);
            G[a].push_back(b);
            G[b].push_back(a);
        }
        int currentPoint;
        for(int query = 0;query < k;++query){
            scanf("%d",&currentPoint);
            init();
            for(int i=1;i<=n;++i){
                for(int j= 0;j<G[i].size();++j){
                    int u = i,v = G[i][j];//边的两个端点
                    if(u == currentPoint || v == currentPoint) continue;
                    Union(u,v);
                }
            }
            int block = 0;//联通块个数
            for(int i = 1;i<=n;++i){
                if(i == currentPoint){
                    continue;
                }
                int fa_i = findFather(i);
                if(vis[fa_i] == false){
                    block++;
                    vis[fa_i] = true;
                }
            }
            printf("%d
    ",block - 1);
        }
        system("pause");
        return 0;
    }
  • 相关阅读:
    Flink基础之实现WordCount程序(Java版本多种写法)
    Redis 在Springboot 中反序列化 LocalDateTime 时报错
    JVM(五)- 堆
    JVM(四)- 虚拟机栈
    JVM(三)- 程序计数器(PC 寄存器)
    JVM(二)- 运行时数据区概述及线程
    JVM(一)
    phpstudy后门漏洞复现
    primefaces 5.x 表达式注入
    ueditor(v1.4.3)文件上传getshell实战复现
  • 原文地址:https://www.cnblogs.com/JasonPeng1/p/12294033.html
Copyright © 2011-2022 走看看