目录
树的重心(有向图的深度优先遍历)
图中点的层次(有向图的宽度优先遍历)
有向图的拓扑序列
//删除节点后最大连通块集合中的最小连通块
#include
#include
#include
using namespace std;
const int N = 10e5+10,M=2*N;
int h[N], e[M], ne[M], idx,n;
bool s[N];
int ans=N;
void add(int a,int b)// 添加一条边a->b
{
e[idx]=b;ne[idx]=h[a],h[a]=idx++;
}
/*
void dfs(int x)//有向图的深度优先遍历
{
s[x]=true;
for(int i=h[x];i!=-1;i=ne[i])
{
int t=ne[i];
if(!s[t])
{
dfs(t);
}
}
}
*/
int dfs(int x)//有向图的深度优先遍历
{
int sum=1;
int res=0;
s[x]=true;
for(int i=h[x];i!=-1;i=ne[i])
{
int t=e[i];
if(!s[t])
{
int s=dfs(t);//除根节点外子节点的数量
res=max(s,res);//删除该接节点后最大连通块数量(节点)
sum+=s;//包括该节点的和他儿子所有的节点数量
}
}
res=max(res,n-sum);//该节点上面连通块的数量
ans=min(res,ans);//z最大连通块结合最小值
return sum;//返回根节点下所有节点的数量
}
int main()
{
memset(h,-1,sizeof h);
cin>>n;
for (int i = 0; i < n-1; i ++ ){
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
dfs(1);
cout<
#include
#include
#include
#include
#include
using namespace std;
const int N=10e5,M=N*2;
int h[N],e[M],ne[M],idx;
int q[N],n,m;
void add(int a,int b)
{
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
int bfs()
{
memset(q,-1,sizeof q);
queue t;
t.push(1);
q[1]=0;
while(t.size())
{
int k=t.front();
t.pop();
for(int i=h[k];i!=-1;i=ne[i]){
int tmp=e[i];
if(q[tmp]==-1){
q[tmp]=q[k]+1;
t.push(tmp);
}
}
}
return q[n];
}
int main()
{
cin>>n>>m;
memset(h,-1,sizeof h);
for(int i=0;i>x>>y;
add(x,y);
}
cout<
#include
#include
#include
using namespace std;
const int N = 10e5,M=2*N;
int h[N], e[M], ne[M], idx;
int d[N],q[N];
int n,m;
void add(int a, int b) // 添加一条边a->b
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
bool topsort()
{
int t=0,sz=-1;
for(int i=0;i<=n;i++)
{
if(d[i]==0)q[++sz]=i;
}
while(t<=sz)
{
int tmp=q[t++];
for(int i=h[tmp];i!=-1;i=ne[i])
{
int s=e[i];
d[s]--;
if(d[s]==0)q[++sz]=s;
}
}
return sz==n;
}
int main()
{
cin>>n>>m;
memset(h,-1,sizeof h);
for(int i=0;i>x>>y;
add(x, y);
d[y]++;
}
if(topsort())
{
for(int i=1;i<=n;i++)
{
cout<