PTA1013 - Battle Over Cities - 求连通块模板题
题意
第一行给出n、m、k,表示有n个城市,给出m条路,k个被敌人占领的点。
接下去给出m行,每行有两个数x、y,表示x和y之间存在一条路(双向路)。
最后给出k个被敌人占领的点(设每个点为id),如果点id被占领,那么和点id相连接的所有路都无法走。
问如果我们想要剩下的所有城市可以相互访问到,需要再修几条路。
思路
第一种思路:在k个城市遍历的时候,我们求出除了id点之外,剩下的城市中有多少连通块,每次询问把剩下所有城市连接起来需要修建道路的答案数量就是:连通块 - 1。代码见下方。
第二种思路:并查集,见:https://zhanglong.blog.csdn.net/article/details/113777370。
第三种思路:拓扑排序,自行查找。
注意
-
牛客上交的话要特判一下n==1的情况,PTA不用。
-
因为DFS所以要标记,但是因为本题间接求联通块所以不用回溯标记,这个要记住。
联通块AC代码
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
const int N=1010;
int n,m,k,e[N][N],id;
bool book[N];
void dfs(int x)
{
for(int i=1;i<=n;i++)
{
if(i!=id&&e[x][i]&&!book[i]) // if(i!=x&&e[x][i]&&!book[i])
book[i]=1,dfs(i); // book[i]=0; 求连通块的话,不用递归回溯
}
}
int main()
{
cin>>n>>m>>k;
if(n==1)
{
cout<<0<<endl;
return 0;
}
for(int i=0;i<m;i++)
{
int x,y;
cin>>x>>y;
e[x][y]=e[y][x]=1;
}
for(int i=0;i<k;i++)
{
int ans=0;
cin>>id; // 排出x点和与x相连的所有边,求剩下所有点的连通块
memset(book,0,sizeof(book));
for(int j=1;j<=n;j++)
{
if(id!=j&&!book[j])
book[j]=1,dfs(j),ans++;
}
cout<<ans-1<<endl;
}
return 0;
}
分类:
图论
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
2020-03-06 寒假Day43:HDU1540 - Tunnel Warfare - 线段树+区间合并
2020-03-06 寒假Day42:JAVA-OOP-java核心类