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

Posted 辰曦~文若

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的时候没访问过该点,即表明该点与前面的点不属于同一个分支,相当于新的分支。
所以只要统计一下1~n中dfs多少次,就有多少个联通分支
删除的点最开始标记一下,就不会访问到了。

技术分享
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <cstring>
using namespace std;
const int maxn=1000+5;
int n,m,k;
int check[maxn]; //先标记哪些点会check,防止有重复的点做重复的工作
int ans[maxn]; //删掉节点i后剩余的连通分支数目
int vis[maxn]; //用于dfs时候的标记
struct Edge{
    int to;
    int next;
}edge[maxn*maxn];
int head[maxn];
int tot;

void init(){
    memset(head,-1,sizeof(head));
    tot=0;
}
void add(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}

void dfs(int u){
    vis[u]=1;
    if(head[u]==-1)
        return;
    for(int k=head[u];k!=-1;k=edge[k].next){
        int v=edge[k].to;
        if(!vis[v]){
            dfs(v);
        }
    }
}
/*
对于要check的点,求删除后的联通分支数,存储在ans数组里
*/
void solve(){
    memset(ans,0,sizeof(ans));
    for(int i=1;i<=n;i++){
        //如果i是要被询问的
        if(check[i]){
            memset(vis,0,sizeof(vis));
            vis[i]=1;
            for(int j=1;j<=n;j++){
                //每次有没被访问过的节点,表明又是一个新的联通分支
                if(!vis[j] && j!=i){
                    dfs(j);
                    ans[i]++;
                }
            }
        }
    }
}
int main()
{
    int u,v;
    init();
    scanf("%d %d %d",&n,&m,&k);
    for(int i=0;i<m;i++){
        scanf("%d %d",&u,&v);
        add(u,v);
        add(v,u);
    }
    memset(check,0,sizeof(check));
    vector<int>query;
    for(int i=0;i<k;i++){
        scanf("%d",&u);
        check[u]=1;
        query.push_back(u);
    }
    solve();
    for(int i=0;i<query.size();i++){
        u=query[i];
        printf("%d\n",ans[u]-1);
    }
    return 0;
}
View Code

 










以上是关于PAT甲题题解-1013. Battle Over Cities (25)-求联通分支个数的主要内容,如果未能解决你的问题,请参考以下文章

PAT 1013. Battle Over Cities

PAT1013: Battle Over Cities

pat 1013 Battle Over Cities(25 分) (并查集)

PAT A1013 Battle Over Cities (25 分)

PAT Advanced 1013 Battle Over Cities (25分)

PAT Advanced Level 1013 Battle Over Cities (25)(25 分)