12.9日+基環樹 dfs找環
阿新 • • 發佈:2018-12-21
基環樹就是在一棵樹上加一條邊的圖。一般結合其他樹形dp、樹的直徑等題型考察,有一定難度。
處理方法一般都是先找環。
例如這道題目,BZOJ 1791 [Ioi2008] Island 島嶼:https://www.lydsy.com/JudgeOnline/problem.php?id=1791,求基環樹森林的樹直徑之和。後面的樹形dp不會,但找環和求以某點為根的子樹的深度還是可以的,用dfs。
先粘上求環中點的dfs程式碼(以前都是並查集,,,):
#include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <iostream> #include<algorithm> #include <set> #include <queue> #include <stack> #include<vector> #include<map> #include<ctime> #define ll long long using namespace std; const int N=100010,M=1000010; int head[N]; int ver[M]; int edge[M]; int Next[M]; bool v[N]; int tot; priority_queue< pair<int,int> >Q; void add(int x,int y,int z) { ver[++tot]=y; edge[tot]=z; Next[tot]=head[x]; head[x]=tot; } bool flag[N]; int path[N]; int sum; int dfs(int x,int pre) { flag[x]=1; for(int i=head[x];i;i=Next[i]) { int vv=ver[i]; //cout<<vv<<endl; if(!flag[vv]) { int index= dfs(vv,x); if(!index)continue; if(index!=-1)path[++sum]=vv; if(index==vv)return -1; else return index; } else if(vv!=pre) { //cout<<vv<<" "<<pre<<endl; path[++sum]=vv; return vv; } } } int main() { int n,m; cin>>n>>m; for(int i=1;i<=m;++i) { int x,y,z; cin>>x>>y>>z; add(x,y,z); add(y,x,z); } dfs(1,-1); for(int i=1;i<=sum;++i)cout<<path[i]<<" "; cout<<endl; }
The end;