PAT甲级 1013 Battle Over Cities (DFS、连通子图)

题目说明:

给定一个无向图,如果去掉某个节点,计算剩下的点形成一个连通图最少需要加多少条边

输入输出解释

Sample Input:

3 2 3 //3个节点,2条边,需要计算去掉3个点的情况
1 2
1 3
1 2 3

Sample Output:

1
0
0

思路

实际就是求去掉一个点后图连通子图数 - 1,学过图算法就知道,dfs就是干这个的

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<bool>vis;
void DFS(vector<vector<int>>&map, int pos) //注意这里一定加&,不然234测试点会超时或者超内存,带着2维数组递归,不超才怪
{
    for(int i = 1; i < map[0].size(); i++)
    {
        if(vis[i] == 0 && map[pos][i] == 1)
        {
            vis[i] = 1;
            DFS(map, i);
        }
     }
}
int main()
{
    int city_n, edge_n, city_concern_n;
    cin>>city_n>>edge_n>>city_concern_n;
    vector<vector<int>>map(city_n + 1, vector<int>(city_n + 1, 0));
    vector<int>ans;
    vis.resize(city_n + 1);
    for(int i = 0; i < edge_n; i++)
    {
        int x, y;
        cin>>x>>y;
        map[x][y] = 1;
        map[y][x] = 1;
    }
    
    for(int i = 0; i < city_concern_n; i++)
    {
        int t, sum = 0;
        cin>>t;
        for(int j = 0; j < vis.size(); j++)
            vis[j] = 0;
        vis[0] = 1;
        vis[t] = 1;
        while(find(vis.begin(), vis.end(), 0) != vis.end())
        {
            int pos = find(vis.begin(), vis.end(), 0) - vis.begin();
            vis[pos] = 1;
            sum++;
            DFS(map, pos);
        }
        ans.push_back(sum - 1);
    }
 for(int i = 0; i < city_concern_n; i++)
 {
     if(i == city_concern_n - 1)
         cout<<ans[i];
     else
         cout<<ans[i]<<endl;
 }
     
}

结果

posted @ 2021-02-27 22:41  liushz  阅读(51)  评论(0)    收藏  举报