Vertices Beyond K
National Olympiad — Municipal round (2020 season)
Submission name: periphery.cpp
Problem summary
In a connected undirected unweighted graph, list the vertices whose shortest-path distance from C is strictly greater than K.
Input
N M C K, followed by M undirected edges.
Output
The count P, then the P vertex labels in increasing order, one per line.
Constraints
1 ≤ N,M ≤ 100,000; 0 ≤ K < N; the graph is connected and simple.
Worked example
An independently prepared example for this explanation.
Input
7 8 2 1 1 2 1 3 1 4 1 5 2 3 2 6 2 7 3 6
Output
2 4 5
Solution analysis
- Breadth-first search from C visits vertices by increasing distance. Record each vertex’s distance when it is first enqueued, so every vertex enters the queue once.
- After BFS, scan labels 1…N and collect precisely those with distance greater than K. This scan gives the requested sorted order without sorting.
- In example 1, vertices 1,3,6,7 are one edge from vertex 2; vertices 4 and 5 need two edges. For K=1 only 4 and 5 belong to the periphery.
Why it works
BFS first discovers every vertex through a shortest path: all shorter-distance vertices have already been expanded before a new distance layer is reached. Thus the recorded distances equal the definition in the statement. The final comparison selects exactly distances strictly above K, and label order makes the output increasing.
Watch out. The comparison is >K, not ≥K. Mark vertices when enqueuing. Print only the count line when P=0.
Commented C++17 solution
An independently written complete program with standard headers.
#include<iostream>
#include<queue>
#include<vector>
// Algorithm: Breadth-first search from C visits vertices by increasing distance.
using namespace std;
int main(){
int n,m,center,k;
cin>>n>>m>>center>>k;
vector<vector<int>>adjacent(n+1);
while(m--){
int u,v;
cin>>u>>v;
adjacent[u].push_back(v);
adjacent[v].push_back(u);
}
vector<int>distance(n+1,-1);
queue<int>pending;
distance[center]=0;
pending.push(center);
while(!pending.empty()){
int vertex=pending.front();
pending.pop();
for(int next:adjacent[vertex]){
if(distance[next]==-1){
distance[next]=distance[vertex]+1;
pending.push(next);
}
}
}
vector<int>answer;
for(int vertex=1;vertex<=n;vertex++){
if(distance[vertex]>k){
answer.push_back(vertex);
}
}
cout<<answer.size()<<'\n';
for(int vertex:answer){
cout<<vertex<<'\n';
}
}