题解:P14615 [2019 KAIST RUN Fall] Capital
题解:P14615 [2019 KAIST RUN Fall] Capital
可以观察到,“首都”的要求是人们必须从这个点离开,去到别的点,也就是不能有其他的边指向这个点,即入度为
因此,可以得到:
形式化题意:在给定的点数为
建好图,依次把每个点作为“首都”开始 DFS/BFS,所有可以走到的点全部标为“不可成为首都”,最后枚举一遍所有点,把没有带标记的点记录输出即可。
因为每一条路的长度你都可以自己设定,所以不用管题目里“人们尝试沿最短路径移动”这一句话,关注图的连通性就行。
时间复杂度为
示例代码如下:
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
int n, m, visited[510], can_vis[510], ansls[510], idx;
vector<int> a[510];
void dfs(int p, int start){
if(visited[p])
return;
if(p != start)
can_vis[p] = 1; // 如果可以走到,并且不是初始点,则这个点不能成为首都
visited[p] = 1;
for(int i = 0; i < a[p].size(); i++)
dfs(a[p][i], start);
return;
}
int main(){
cin >> n >> m;
for(int i = 0; i < m; i++){
int x, y;
cin >> x >> y;
a[x].push_back(y);
} // 建图
for(int i = 1; i <= n; i++){
memset(visited, 0, sizeof visited);
dfs(i, i);
} // 遍历
for(int i = 1; i <= n; i++)
if(can_vis[i] == 0){
ansls[idx] = i;
idx++;
} // 统计答案
cout << idx << endl;
for(int i = 0; i < idx; i++)
cout << ansls[i] << endl; // 输出
}
求赞 qwq