PAT甲级1013 Battle Over Cities

求出不带特定点有几个连通分量,答案就是连通分量-1

首先解释一下连通分量

无向图G的极大连通子图称为G的连通分量( Connected Component)。任何连通图的连通分量只有一个,即是其自身,非连通的无向图有多个连通分量。

简单来说就是如果一个图任何一点都可以到达,那么这个图就是连通图,连通图只有一个连通分量,而对于不是连通图的图来说,有几部分就是几个连通分量

这道题首先给我们一个图,然后让我们求把图中的某个点去掉之后,剩下的点至少还需要恢复几条路才可以成为连通图,我们把去掉那个点之后,每一个连通的那一部分当成一个点,也就是一个连通分量,问题就变成了剩下的n个点,恢复几条边能使他们连通,只需要n-1条边即可

求连通分量只需要用一个dfs即可,用一个布尔数组v代表我们是否访问过这个点,用二维数组w表示x和y之间是否有路,如何去掉特定点呢,其实就是直接把它的v设为true,这样我们寻找有几个连通分量就跟这个点无关,求出有n个连通分量,答案就是n-1,因为n个部分,只需要n-1条边就可以将这n部分连接起来

#include
#include
using namespace std;
int n,m,k;
bool w[1010][1010];
bool v[1010];
void dfs(int x) {
    v[x]=true;
    for(int i=1;i<=n;i++) {
        if(!v[i]&&w[x][i]) {
            dfs(i);
        }
    }
}
int main() {
    scanf("%d%d%d",&n,&m,&k);
    int x,y;
    for(int i=1;i<=m;i++) {
        scanf("%d%d",&x,&y);
        w[x][y]=w[y][x]=true;
    }
    while(k--) {
        int ans=0;
        scanf("%d",&x);
        memset(v,0,sizeof(v));
        v[x]=true;
        for(int i=1;i<=n;i++) {
            if(!v[i]) {
                dfs(i);
                ans++;
            }
        }
        printf("%d\n",ans-1);
    }
    return 0;
}

你可能感兴趣的:(PAT甲级,图论,图论)