樹與圖的遍歷 學習記錄
阿新 • • 發佈:2018-12-09
樹與圖的深度優先遍歷,樹的DFS序、深度和重心
DFS
//深度優先遍歷 dfs
void dfs(int x)
{
v[x]=1;//記錄點x被訪問過,v是visit的縮寫
for (int i=head[x];i;i=Next[i])
{
int y=ver[i];
if (v[y]) continue;//點y已經被訪問過了
dfs(y);
}
}
樹的DFS序
//樹的DFS序
void dfs(int x)
{
a[++m]=x;//a陣列儲存DFS序
v[x]=1;//記錄點x被訪問過
for (int i=head[x];i;i=Next[ i])
{
int y=ver[i];
if (v[y]) continue;
dfs(y);
}
a[++m]=x;
}
樹的深度
//樹的深度
void dfs(int x)
{
v[x]=1;
for (int i=head[x];i;i=Next[i])
{
int y=ver[i];
if (v[y]) continue;
d[y]=d[x]+1;//從父節點x到子節點y遞推,計算深度
dfs(y);
}
}
樹的重心
//樹的重心
void dfs(int x)
{
v[x]=1;//子樹x的大小
size[x]=1;
int max_part=0;//刪掉x後分成的最大子樹的大小
for (int i=head[x];i;i=Next[i])
{
int y=ver[i];
if (v[y]) continue;//點y已經被訪問過了
dfs(y);
size[x]+=size[y];//從子節點向父節點遞推
max_part=max(max_part,size[y]);
}
max_part=max(max_part,n-size[x]);//n為整棵樹的節點數目
if (max_part<ans)
{
ans=max_part;//全域性變數ans記錄重心對應的max_part值
pos=x;//全域性變數pos記錄了重心
}
}
圖的連通塊劃分
//圖的連通塊劃分
void dfs(int x)
{
v[x]=cnt;
for (int i=head[x];i;i=Next[i])
{
int y=ver[i];
if (v[y]) continue;
dfs(y);
}
}
for (int i=1;i<=n;++i)//在int main()中
if (!v[i])
{
++cnt;
dfs(i);
}
樹與圖的廣度優先遍歷,拓撲排序
BFS
void bfs()
{
memset(d,0,sizeof(d));
queue<int>q;
q.push(1);
d[1]=1;
while (q.size()>0)
{
int x=q.front();
q.pop();
for (int i=head[x];i;i=Next[i])
{
int y=ver[i];
if (d[y]) continue;
d[y]=d[x]+1;
q.push(y);
}
}
}
拓撲排序
void add(int x,int y)//在鄰接表中新增一條有向邊
{
ver[++len]=y,Next[len]=head[x],head[x]=len;
deg[y]++;
}
void topsort()//拓撲排序
{
queue<int>q;
for (int i=1;i<=n;++i)
if (!deg[i]) q.push(i);
while (q.size())
{
int x=q.front();
q.pop();
a[++cnt]=x;
for (int i=head[x];i;i=Next[i])
{
int y=ver[i];
if (--deg[y]==0) q.push(y);
}
}
}
int main()
{
cin>>n>>m;//點數、邊數
for (int i=1;i<=m;++i)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
}
topsort();
for (int i=1;i<=cnt;++i)
printf("%d ",a[i]);
printf("\n");
}