๐๊ณต๋ถํ ๊ฑฐ List๐
- ์ข ๋ง๋ถ - 28. ๊ทธ๋ํ์ ๊น์ด ์ฐ์ ํ์
DFS_Depth First Search
vector<vector<int>> adj;
vector<bool> visited;
void dfs(int here) {
visited[here] = true;
for(int i=0; i<adj[here].size(); ++i) {
int there = adj[here][i];
if(!visited[there]) dfs(there);
}
}
void dfsAll() {
visited = vector<int>(adj.size(), false);
for(int i=0; i<adj.size(); ++i) {
if(!visited[i]) dfs(i);
}
}
Time/Space Complexity
์ธ์ ๋ฆฌ์คํธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ : O(|V|+|E|)
์ธ์ ํ๋ ฌ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ : O(|V|^2)
ํฌ์ํ๋ ฌ(spare matrix)์ธ ๊ฒฝ์ฐ์๋ ์ธ์ ๋ฆฌ์คํธ๋ฅผ, ๋ฐ์งํ๋ ฌ(dense matrix)์ธ ๊ฒฝ์ฐ์๋ ์ธ์ ํ๋ ฌ์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ณต๊ฐ์ ๋ญ๋น๋ฅผ ์ค์ผ ์ ์๋ ๋ฐฉ๋ฒ์ด๋ค.
์์กด์ฑ ๊ทธ๋ํ(Dependency Graph) : ๊ฐ ์์ ์ ์ ์ ์ผ๋ก ํํํ๊ณ ์์ ๊ฐ์ ์์กด ๊ด๊ณ๋ฅผ ๊ฐ์ ์ผ๋ก ํํํ ๋ฐฉํฅ ๊ทธ๋ํ
DAG : ์ฌ์ดํด ์๋ ๋ฐฉํฅ ๊ทธ๋ํ.
DAG์ ์ ์ ์ ๋ฐฐ์ดํ๋ ๋ฌธ์ ๋ฅผ ์์์ ๋ ฌ(Topological Sort)๋ผ๊ณ ํ๋ค.
dfs()๊ฐ ์ข ๋ฃ๋ ๋๋ง๋ค ์ ์ ์ ๋ฒํธ๋ฅผ ์ ์ฅํด๋๊ณ , dfsAll()์ด ์ข ๋ฃํ ๋ค ๊ธฐ๋ก๋ ์ ์ ๋ค์ ์์๋ฅผ ๋ค์ง์ผ๋ฉด ์์์ ๋ ฌ์ ๊ฒฐ๊ณผ๊ฐ ๋๋ค.
๋ฌธ์ : ๋จ์ด๋ค์ ๋ชฉ๋ก์ด ์์๋๋ก ์ฃผ์ด์ง ๋ ์ด ์ธ์ด์์ ์ํ๋ฒณ์ ์์๋ฅผ ๊ณ์ฐ.
โก๏ธkeypointโก๏ธ
- ๊ฐ ์ํ๋ฒณ์ ์ ์ ์ผ๋ก ํํํ๊ณ , ์์๋ ๋ฐฉํฅ๊ทธ๋ํ๋ก ํํํ๋ค.
- ์ฌ์ดํด์ด ์๋ค๋ฉด ์์์ ๋ ฌ์ด ์๋๋ค. ์ฌ์ดํด์ ์ ๋ฌด๋ฅผ ํ์ธํ๋ ๋ฐฉ๋ฒ์ ์ค๋ฅธ์ชฝ์์ ์ผ์ชฝ์ผ๋ก ๊ฐ์ ์ด ์๋์ง ํ์ธํ๋ฉด๋๋ค.
๐**ํด๋ต(์ฝ๋)**๐
/*
* ๊ณ ๋์ด ์ฌ์ ๋ฌธ์ ์ ๊ทธ๋ํ ์์ฑ
*/
vector<vector<int>> adj;
void makeGraph(const vector<string>& words) {
adj = vector<vector<int>>(26,vector<int>(26,0));
for(int i=1; i<words.size(); ++i) {
int j=i-1, len = min(words[i].size(), words[j].size());
for(int k=0; k<len; ++k) {
if(words[i][k] != words[j][k]){
int a = words[i][k] - 'a';
int b = words[j][k] - 'a';
adj[a][b] = 1;
break;
}
}
}
}
//๊น์ด ์ฐ์ ํ์์ ์ด์ฉํ ์์์ ๋ ฌ
vector<int> visited, order;
void dfs(int here) {
visited[here] = 1;
for(int there = 0; there<adj.size(); ++there) { //์ ์ฒด ๋
ธ๋์ ๊ฐ์๋งํผ
//๋ง์ฝ here->there ๊ฐ์ ์ด ์๊ณ , ์์ง there์ ๋ฐฉ๋ฌธํ์ง ์์๋ค๋ฉด, there ๋ฐฉ๋ฌธ
if(adj[here][there] && !visited[there]) dfs(there);
}
order.push_back(here); //order์ here ์ถ๊ฐ
}
vector<int> topologicalSort() {
visited = vector<int>(adj.size(), false); //์ด๊ธฐํ
order.clear(); //์์ ๋ฐฐ์ด ์ด๊ธฐํ
for(int i=0; i<adj.size(); ++i) { //์ ์ฒด๋
ธ๋์ ์๋งํผ
if(!visited[i]) dfs(i); //i-๋
ธ๋ ๋ฐฉ๋ฌธ์ํ๋ค๋ฉด, ๋ฐฉ๋ฌธํ๊ธฐ
}
//#include <algorithm>
reverse(order.begin(), order.end()); //order ์์ ๊ฑฐ๊พธ๋ก ์ ๋ ฌ
//์ญ๋ฐฉํฅ ๊ฐ์ ์ด ์๋์ง ํ์ธํ๊ณ , ์๋ค๋ฉด ๋น ๋ฒกํฐ๋ฅผ ๋ฐํ
for(int i=0; i<adj.size(); ++i) {
for(int j=i+1; j<adj.size(); ++j) {
if(adj[order[j]][order[i]]) return vector<int>();
}
}
return order;
}
๊ทธ๋ํ์ ๋ชจ๋ ๊ฐ์ ์ ์ ํํ ํ ๋ฒ์ฉ ์ง๋์ ์์์ ์ผ๋ก ๋์์ค๋ ๊ฒฝ๋ก๋ฅผ ์ฐพ๋ ๋ฌธ์
- ๊ทธ๋ํ์ ๋ชจ๋ ์ ์ ๋ค์ด ์ง์์ ์ด์ด์ผ๋ง ์ค์ผ๋ฌ ์ํท์ด ์กด์ฌํ ์ ์๋ค.
findRandomCircuit(u)
: ์ ์ u์์ ์์ํด ์์ง ๋ฐ๋ผ๊ฐ์ง ์์ ๊ฐ์ ์ค ํ๋๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉฐ ์์์ ๊ฒฝ๋ก๋ฅผ ๋ง๋๋ ํจ์/๋์ด์ ๋จ์ ๊ฐ์ ์ด ์์๋๊น์ง.
vector<vector<int>> adj;
void getEulerCircuit(int here, vector<int>& circuit) {
for(int there=0; there<adj[here].size(); ++there) {
while(adj[here][there]>0){
adj[here][there]--;
adj[there][here]--;
getEulerCircuit(there, circuit);
}
}
circuit.push_back(here);
}