문제 URL : https://www.acmicpc.net/problem/6543
6543번: 그래프의 싱크
각 테스트 케이스마다 한 줄에 걸쳐 bottom(G)의 모든 노드를 출력한다. 노드는 공백으로 구분해야 하며, 오름차순이어야 한다. 만약, bottom(G)가 공집합이면 빈 줄을 출력한다.
www.acmicpc.net
문제 접근법 :
scc알고리즘 문제입니다.
bottom(G) 를 구하기위해선 scc안에서 outdegree가 없는
노드르 찾아야합니다.
소스코드 :
#include <bits/stdc++.h>
using namespace std;
int n,m;
vector<vector<int>> adj,vscc;
vector<int> check,finish,st,outdegree,cscc;
int id=0;
int color=0;
void input(){
cin>>n;
if(n==0)exit(0);
cin>>m;
int a,b;
adj = vector<vector<int>>(n+1);
for(int i=0;i<m;i++){
cin>>a>>b;
adj[a].push_back(b);
}
}
int scc(int cur){
check[cur]=++id;
int root = check[cur];
st.push_back(cur);
for(int next:adj[cur]){
if(check[next]==0)root=min(root,scc(next));
else if(!finish[next]) root= min(root,check[next]);
}
if(check[cur]==root){
vector<int> v;
while(true){
int node = st.back();
st.pop_back();
v.push_back(node);
finish[node]=1;
cscc[node]=color;
if(cur==node)break;
}
color++;
vscc.push_back(v);
}
return root;
}
void solve(){
id = color=0;
vscc.clear();
cscc = outdegree = check = finish=vector<int>(n+1);
for(int i=1;i<=n;i++)if(check[i]==0)scc(i);
for(int i=1;i<=n;i++){
for(int next:adj[i]){
if(cscc[i]!=cscc[next]){
outdegree[cscc[i]]++;
}
}
}
vector<int>res;
for(int i=0;i<color;i++){
if(!outdegree[i]){
for(int cur : vscc[i]){
res.push_back(cur);
}
}
}
sort(res.begin(),res.end());
for(int i:res)cout<<i<<" ";
cout<<"\n";
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
//freopen("input.txt","r",stdin);
while(true){
input();
solve();
}
}
궁금한점 혹은 모르는점 어떤 질문이든 댓글은 언제나 환영입니다.
'백준' 카테고리의 다른 글
백준 7579 앱 (0) | 2023.12.11 |
---|---|
백준 13164 행복 유치원 (0) | 2023.12.10 |
백준 9202 Boggle (1) | 2023.12.10 |
백준 1506 경찰서 (2) | 2023.12.09 |
백준 4196 도미노 (0) | 2023.12.07 |