1013 Battle Over Cities (25 分)

PAT (Advanced Level) Practice 笔记

记录做PAT (Advanced Level) Practice时遇到的坑和总结


一、描述

删除图的某个节点,求联通分量的个数


二、题目链接

1013 Battle Over Cities (25 分)

三、代码

1.AC

#include <iostream>
using namespace std;
const int MaxSize=1005;
int Graph[10][MaxSize][MaxSize]={{{0}}};
int id_Graph=0;
int res=0; //输出结果,子图数量
int nodes=0; //已经遍历的节点个数
bool visited[MaxSize]={false};
void Print()
{
    for (int i=0;i<3;i++)
    {
        for (int j=0;j<3;j++)
            cout << Graph[id_Graph][i][j] << ' ';
        cout << endl;
    }
}
void dfs(int v,int n)
{
    //cout << "test" << endl;
    for (int w=0;w<n;w++)
    {
        if (Graph[id_Graph][v][w]==1 && !visited[w])
        {
            visited[w]=true;
            nodes++;
            //cout << "now nodes=" << nodes << endl;
            dfs(w,n);
        }
    }
}
int main()
{
    int n,m,k,tmp1,tmp2,v1,v2;
    scanf("%d %d %d",&n,&m,&k);
    //cout << n << ' ' << m << ' ' << k << endl;
    for (int i=0;i<m;i++)
    {
        scanf("%d %d",&tmp1,&tmp2);
        v1=tmp1-1;
        v2=tmp2-1;
        //数组中的0是节点1
        //cout << tmp1 << ' ' << tmp2 << endl;
        for (int j=0;j<k;j++)  //存储k张图
        {
            Graph[j][v1][v2]=1;
            Graph[j][v2][v1]=1;
        }
    }
    //Print();
    for (;id_Graph<k;id_Graph++)
    {
        //cout << "id_Graph=" << id_Graph << endl;
        scanf("%d",&tmp1);
        v1=tmp1-1;
        //cout << "v1=" << v1 << endl;
        //切断v1与其他点的联系
        for (int j=0;j<n;j++)
        {
            Graph[id_Graph][v1][j]=0;
            Graph[id_Graph][j][v1]=0;
        }
        //Print();
        //遍历所有节点,能联通的排除,计算不连通的子图数量
        //for (int i=0;i<n;i++) cout << visited[i] << endl;
        while (nodes<n) //还有点未被访问
        {
            int vertex=0;
            //cout << nodes << endl;
            for (;vertex<n && visited[vertex];vertex++); //找到未被访问的点
            //cout << "vertex=" << vertex << endl;
            visited[vertex]=true;
            nodes++;
            //遍历和这个点联通的点
            dfs(vertex,n);
            res++;  //遍历退出,与这个点联通的子图已经遍历结束
        }
        //有res个子图,其中有一个是被割断的孤立点,不需要建立连接,剩下每个子图之间都需要一个连接
        int output=res-2;
        cout << output << endl;
        res=nodes=0;
        for (int j=0;j<n;j++) visited[j]=false;
    }
}

2.学习

代码来自 1013. Battle Over Cities (25)-PAT甲级真题(图的遍历,统计强连通分量的个数,dfs)

#include <cstdio>
#include <algorithm>
using namespace std;
int v[1010][1010];
bool visit[1010];
int n;
void dfs(int node) {
    visit[node] = true;
    for(int i = 1; i <= n; i++) {
        if(visit[i] == false && v[node][i] == 1)
            dfs(i);
    }
}
int main() {
    int m, k, a, b;
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 0; i < m; i++) {
        scanf("%d%d", &a, &b);
        v[a][b] = v[b][a] = 1;
    }
    for(int i = 0; i < k; i++) {
        fill(visit, visit + 1010, false);
        scanf("%d", &a);
        int cnt = 0;
        visit[a] = true;
        for(int j = 1; j <= n; j++) {
            if(visit[j] == false) {
                dfs(j);
                cnt++;
            }
        }
        printf("%d\n", cnt - 1);
    }
    return 0;
}

四、总结

  1. 删除图节点可以用visited[i]=true来表示,不需要把连接删除
  2. 保证图的每个节点都被遍历也可以通过完全遍历和visited[i]==false来确定
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_森罗万象

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值