Acme Design is a full service design agency.
Sarah Levin, CEO
表達兩個東東之間的關係
ex: 血緣/人物關係圖、捷運路線圖
點vertex
邊edge
開一個二維矩陣Graph
若兩點有關係就將Graph[u][v]標記為1
否則為0
無向圖時Graph[v][u]也要記錄!
空間複雜度 O( )
假設有ABCDE五個點,其中{A, B}, {A, C}, {B, D}, {C, D}, {D, E}
間有關係,可以用下列鄰接矩陣進行表示:
對於每個點開一個vector,在後面紀錄與其相鄰的點
adj[u].push_back(v);
同樣若是無向圖的時候也要記錄 v-> u
空間複雜度 O(m)
vector<int> adj[M];
int main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < m; i++)
{
int a, b;
cin >> a >> b;
adj[a].push_back(b);
adj[b].push_back(a);
}
}分為BFS(廣度優先搜尋法) 以及 DFS(深度優先搜尋)
BFS (想成水在流)
使用queue存下可以走到但尚未走過的點
然後將走過的點pop(刪除), 繼續走與他相鄰的點
可以用來記錄每個點與原點的距離!
假設每一點的權重均為1(後面會遇到權重不一樣的情況!)
vector <int> adj[M];
bool vis [M]; //紀錄是否走過
int d[M]; //紀錄距離
queue <int> que;
d[1] = 0;
que.push(1);
while (que.size())
{
int now = que.front();
que.pop();
vis[now] = 1;
for (int v:adj[now]) //對於adj[now]中的每一個點都跑一遍
{
if (!vis[v])
{
que.push(v); // 還沒跑過就加入queue
d[v] = d[now] + 1;
vis[v] = 1 //並紀錄已經跑過
}
}
}vector <int>adj[M];
bool vis[M];
DFS(1);
void DFS(int n)
{
vis[n] = 1;
for (int v:adj[n])
{
if (!vis[v])
DFS(v);
}
}Hint: 用區塊分房間,該用dfs or bfs?
將事情的先後順序看成有向圖,當作過該事件後刪除此點
實際演示(白板)
將事情的先後順序看成有向圖,當作過該事件後刪除此點
實際演示(白板)
7 1 7 8 4 2 10 5 9 2 3 5 6 8 1 5 10 8 7 10
vector <int> adj[M];
int deg[M]; //紀錄每個點從哪裡來的! 0即為前面沒有要先做的
int main()
{
memset(deg, 0, sizeof(deg));
for (int i=0; i<m; i++)
{
int u, v;
cin >> u >> v;
adj[u].push_back(v);
deg[v]++;
}
queue <int> que;
for (int i=1; i<=n; i++)
if (deg[i]==0) //若事情前面沒有要先做的事就先跑
que.push(i);
while (que.size())
{
int now = que.front();
que.pop();
for (int v:adj[now])
{
deg[v]--;
if (deg[v] == 0)
que.push(v);
}
}
}Credit: tree-演算法筆記
void dfs(int n, int par)
{
for (int v:adj[n])
if (v != par)
dfs(v, n);
}int d[M];
d[1] = 0; //此處先假設根節點為1, 要將其換成根節點喔!
void dfs(int n, int par)
{
for (int v:adj[n])
if (v != par)
{
d[v] = d[n] +1;
dfs(v, n);
}
}如何記錄深度呢?
struct Node
{
int val;
Node* l;
Node* r;
}