图的遍历——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\n",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\n",block - 1);
    }
    system("pause");
    return 0;
}

原文地址:https://www.cnblogs.com/JasonPeng1/p/12294033.html

时间: 2024-10-07 16:58:54

图的遍历——A1013Battle over cities(25) 求需要添加多少条边才能构成连通图转化为找连通分量(可由DFS 和 并查集来找连通分量)的相关文章

(hdu step 6.1.3)畅通工程(求需要添加多少条边才能让n个点连通)

题目: 畅通工程 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 163 Accepted Submission(s): 132   Problem Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅通工程"的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道

poj 3177 求至少添加多少条边可以成为边-双连通图(有重边)

[题意]:给出一张无向连通图,求添加多少条边可以成为边-双连通图 [思路]:同3352 一样,求出边-双连通分量,缩点就成了一棵树,求这棵树里的出度为1 的点num  结果是(num-1)/2; 但是!!  这里和3352 哟一点不一样就是这里有重边,当有重边的时候,不同low值的两点可能属于同一个边-双连通分量 所以在构图的时候要注意把重边去掉! 1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h>

PAT甲题题解-1013. Battle Over Cities (25)-求联通分支个数

题目就是求联通分支个数删除一个点,剩下联通分支个数为cnt,那么需要建立cnt-1边才能把这cnt个联通分支个数求出来怎么求联通分支个数呢可以用并查集,但并查集的话复杂度是O(m*logn*k)我这里用的是dfs,dfs的复杂度只要O((m+n)*k)这里k是指因为有k个点要查询,每个都要求一下删除后的联通分支数.题目没给定m的范围,所以如果m很大的话,dfs时间会比较小. for一遍1~n个点,每次从一个未标记的点u开始dfs,标记该dfs中访问过的点.u未标记过,说明之前dfs的时候没访问过

PAT Advanced 1034 Head of a Gang (30) [图的遍历,BFS,DFS,并查集]

题目 One way that the police finds the head of a gang is to check people's phone calls. If there is a phone call between A and B, we say that A and B is related. The weight of a relation is defined to be the total time length of all the phone calls mad

acdream 1685 多民族王国(图,DFS,并查集变形)

Problem Description 娜娜好不容易才回忆起自己是娜娜而不是什么Alice,也回忆起了自己要继续探索这个世界的目标,便偷偷溜出皇宫.娜娜发现这个王国有很多个民族组成,每个民族都有自己的方言,更要命的是这些方面差别还很远,这就导致这个王国的人民交流十分困难.娜娜仔细观察并记录了好久,发现总共有m种不同的语言. 突然娜娜发现前面有一群天才在讨论问题,但是奈何语言问题,导致这群人交流非常吃力.不过幸亏的是,这群天才都有一个特殊的能力,只要消耗一个单位的能量即可完全领悟一门新的语言(妈妈

hdoj 2767 Proving Equivalences【求scc&amp;&amp;缩点】【求最少添加多少条边使这个图成为一个scc】

Proving Equivalences Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4263    Accepted Submission(s): 1510 Problem Description Consider the following exercise, found in a generic linear algebra t

数据结构-图的遍历

图的遍历是指从一个顶点出发,访问且仅一次访问图中其余所有顶点,不是所有边的处理.是求图的连通性,拓扑排序,路径求解等问题的基础. 非常基本的图的遍历方法有深度优先搜索法和广度(宽度)优先搜索法. 深度优先搜索,Depth First Search,DFS 深度优先搜索法是树的先根遍历的推广,它的基本思想是:从图G的某个顶点v0出发,访问v0,然后选择一个与v0相邻且没被访问过的顶点vi访问,再从vi出发选择一个与vi相邻且未被访问的顶点vj进行访问,依次继续.如果当前被访问过的顶点的所有邻接顶点

1013. Battle Over Cities (25)

It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any other highways to keep the rest of

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