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;
}

时间: 2024-10-07 17:02:37

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

PAT甲题题解-1007. Maximum Subsequence Sum (25)-求最大子区间和

题意:给出n个数,求最大连续的子区间和,并且输出该区间的第一个和最后一个数. 如果所有数都小于0,那么则输出0,第一个数和最后一个数. 看数据k的范围,就知道肯定不能两层for循环来求区间和,O(n^2)的复杂度肯定超时所以这里肯定要求一遍for循环就能知道结果定义区间l和r,sum为目前[l,r]之间的和一开始l=r=0,sum=a[0]接下来,对于当前第i个数字a[i]如果sum+a[i]>a[i],那么就将a[i]一起加入到区间中去.如果sum+a[i]<a[i],那么还不如不加,直接重

PAT甲题题解-1036. Boys vs Girls (25)-找最大最小,大水题

题意:给出n个人的姓名.性别.ID.分数,让你找出其中哪个妹纸分数最高.哪个汉子分数最低.以及他们的差如果没有妹纸或者汉子,则对应输出Absent,差用NA代替. 就是for一遍找最大最小值,水题 #include <iostream> #include <cstdio> #include <algorithm> #include <string.h> #include <cmath> #include <vector> #defin

PAT甲题题解-1012. The Best Rank (25)-排序水题

排序,水题因为最后如果一个学生最好的排名有一样的,输出的课程有个优先级A>C>M>E那么按这个优先级顺序进行排序每次排序前先求当前课程的排名然后再与目前最好的排名比较.更新 至于查询,建立id与索引的映射即可. #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <map> using namespace s

PAT甲题题解-1110. Complete Binary Tree (25)-(判断是否为完全二叉树)

题意:判断一个节点为n的二叉树是否为完全二叉树.Yes输出完全二叉树的最后一个节点,No输出根节点. 建树,然后分别将该树与节点树为n的二叉树相比较,统计对应的节点个数,如果为n,则为完全二叉树,否则即不是. #include <iostream> #include <cstdio> #include <algorithm> #include <string.h> using namespace std; const int maxn=22; int two

PAT甲题题解-1052. Linked List Sorting (25)-排序

三个注意点: 1.给出的n个节点并不一定都在链表中 2.最后一组样例首地址即为-1 3.输出地址的时候一直忘记前面要补0... #include <iostream> #include <algorithm> #include <cstdio> #include <string.h> using namespace std; const int maxn=100000+5; struct Node{ int addr; int val; int to; bo

PAT甲题题解-1009. Product of Polynomials (25)-多项式相乘

多项式相乘 注意相乘结果的多项式要开两倍的大小!!! #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string.h> using namespace std; //两个多项式相乘 const int maxn=1000+5; int k; //原本定义个exp导致编译错误,没想到定义成exp1.exp2也会编译错误,

PAT甲题题解-1017. Queueing at Bank (25)-模拟

有n个客户和k个窗口,给出n个客户的到达时间和需要的时长有空闲的窗口就去办理,没有的话就需要等待,求客户的平均时长.如果在8点前来的,就需要等到8点.如果17点以后来的,则不会被服务,无需考虑. 按客户的到达时间排序建立一个优先级队列,一开始放入k个窗口,初始结束时间为8*3600然后for循环客户,每次从优先级队列中取出最早结束时间的窗口如果客户比结束时间来的早,就需要等待如果客户比结束时间来的晚,就无需等待最后只要统计那些到达时间在17*3600之前的客户即可. #include <iost

1013. Battle Over Cities (25)——PAT (Advanced Level) Practise

题目信息: 1013. Battle Over Cities (25) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue 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 th

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

1013 Battle Over Cities (25)(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