樹的直徑:(無根)樹上最長兩點間的最長路徑,兩次dfs即可,第一次dfs任選一點u,找到距離它最遠的點s,再從點s進行一次dfs,找到距離s最遠的點t,則s-t之間的路徑就是樹的直徑。證明:
#include#include#include#include#includetypedef long long ll;using namespace std;
const int maxn=10005;
ll d[maxn];
struct ksd
g[maxn];
int vis[maxn];
int head[maxn],cnt;
void add(int u,int v,int len)
void dfs(int x)
return ;
}int main()
d[1]=0;
dfs(1);
int m;
ll s=0;
for(int i=1;i<=n;i++)
d[i]=0;
}dfs(m);
ll ans=0;
for(int i=1;i<=n;i++)
ans=max(ans,d[i]);
printf("%lld\n",ans);
}
#include#include#includeusing namespace std;const int maxn=200005;
int n,m;
struct pg[maxn];
int head[maxn],d[maxn],vis[maxn];
int cnt=0;
void add(int u,int v,int len)
void dfs(int x)
return ;
}int main()
d[i]=0;
}dfs(m);
int ans=0;
for(int i=1;i<=n;i++)
ans=max(ans,d[i]);
// cout《給你一張無向圖,問你這張圖是否是乙個caterpillar,caterpillar必須滿足是乙個連通圖,無環,切存在一條路徑,使圖中所有的點距離該路徑上點的最小距離為1或0
易知改圖是一棵樹,首先並查集判斷是否聯通,先找到直徑,再判斷所有點距離直徑距離
#include#include#includeusing namespace std;
const int maxn=605;
int fa[maxn],head[maxn],d[maxn],ans[maxn],vis[maxn];
struct pg[maxn*2];
int mp[maxn][maxn];
int fi(int x)
int cnt=0;
void add(int u,int v)
void dfs(int x)
return ;
}int n,m,p,q,k=0;
bool dfs(int z)
vis[z]=1;
for(int i=head[z];i;i=g[i].next)
}return false;
}int main()
scanf("%d",&m);
bool f=1;
if(m!=n-1)
f=0;
for(int i=1;i<=m;i++)
for(int i=1;i<=n;i++)
if(fi(i)!=fi(1))
if(f==0)
dfs(1);
int s=0;
for(int i=1;i<=n;i++)
d[i]=0;
}dfs(p);
s=0;
for(int i=1;i<=n;i++)
d[i]=0;
}dfs(p);
for(int i=1;i<=n;i++)
if(j>n)}}
if(f==0)
else printf("graph %d is a caterpillar.\n",++cas);
}}
大雪將城鎮的街道覆蓋了,兩輛鏟雪機從同一城市出發,要求將所有街道得雪都鏟完,任意一輛鏟雪機可以鏟任意一條街道,最後兩輛車可以停在任意一處,問兩輛車的最少運動長度
有些道路可以經過一次,但有些街道需要經過兩次,那麼即找到一條最長的距離,車子只要走一趟,易知這條路徑即為直徑,故答案為所有邊的長度*2-直徑
#include#include#includeusing namespace std;const int maxn=200005;
int n,m;
struct pg[maxn];
int head[maxn],d[maxn],vis[maxn];
int cnt=0;
void add(int u,int v,int len)
void dfs(int x)
return ;
}int main()
sum=sum*2;
d[1]=0;
dfs(1);
int m;
int s=0;
for(int i=1;i<=n;i++)
d[i]=0;
}dfs(m);
int ans=0;
for(int i=1;i<=n;i++)
ans=max(ans,d[i]);
// cout《給你一張圖,已知兩兩之間的距離為1,問你找出使距離某個點最遠距離最小的點,即找到直徑,若直徑上的點為奇數,則為中間的,若為偶數,則為中間兩個,注意輸入給的距離是讓我們建樹的
#include#include#include#includeusing namespace std;
const int maxn=10005;
int vis[maxn],head[maxn],cnt,v0[maxn];
struct pg[maxn];
struct qp[maxn];
int d[maxn],ans[maxn];
//int sum=0;
void add(int u,int v)
int ma; int n;
void dfs(int x)
return ;
}int q;
int l;
bool dfs(int z)
vis[z]=1;
for(int i=head[z];i;i=g[i].next)
}return false;
}int main()
for(int i=2;i<=n;i++)
d[k]=0;
}dfs(c);
s=0;
for(int i=1;i<=n;i++)
d[k]=0;
}dfs(c);
ans[++l]=c;
if(l%2==0)g[maxn];
void add(int u,int v)
int ma=1e9;
int n;
void dfs(int u)
if(n-d[u]>ans[u])
ans[u]=n-d[u];
if(ma>ans[u])
ma=ans[u];
}int main()
for(int i=1;i求樹的重心,輸出字典序最小的
#include#include#includeusing namespace std;
const int maxn=100005;
int cnt,d[maxn],vis[maxn],head[maxn];
struct pg[maxn];
void add(int u,int v)
int ans1,ans2;
int n;
void dfs(int u)
sum=max(sum,n-d[u]);
if((sum}int main()
for(int i=1;idfs(1);
printf("%d %d\n",ans1,ans2);
}}
樹的重心 樹的直徑
樹的重心 樹的重心定義為 找到乙個點,其所有的子樹中最大的子樹節點數最少,那麼這個點就是這棵樹的重心,刪去重心後,生成的多棵樹盡可能平衡.實際上樹的重心在樹的點分治中有重要的作用,可以避免n 2的極端複雜度 從退化鏈的一端出發 保證nlogn的複雜度,利用樹型dp可以很好地求樹的重心.求樹的重心 模...
樹的直徑 樹的重心
樹的直徑 定義 那麼樹上最遠的兩個點,他們之間的距離,就被稱之為樹的直徑。樹的直徑的性質 1.直徑兩端點一定是兩個葉子節點。2.距離任意點最遠的點一定是直徑的乙個端點,這個基於貪心求直徑方法的正確性 可以得出。3.對於兩棵樹,如果第一棵樹直徑兩端點為 u,v 第二棵樹直徑兩端點為 x,y 用條邊將兩...
樹的直徑與重心
樹的直徑,指樹上最長的不重複經過同乙個點的路徑。方法 先從任意一點p pp出發,找離它最遠的點q qq,再從點q qq出發,找離它最遠的點w ww,w ww到q qq的距離就是的直徑 具體實現可以使用兩次dfs dfsdf s。演算法證明 反證法 include using namespace st...