随笔 - 531  文章 - 0  评论 - 3  阅读 - 10215 

 

1.树的最大独立集

任选一个点作为根,有了以下得状态

 f[i][0/1] 

f[i][0] += max(f[y][0], f[y][1]

f[i][1] += f[i][0]

#include <iostream>
#include <vector>
using namespace std; 
 const int N=6005;
 vector<vector<int> >g(N);
 int n,vis[N],f[N][2];
 
 void dp(int x){
 	for(int i=0;i<g[x].size();i++){
 		int y=g[x][i];
 		dp(y);
 		f[x][0]+=max(f[y][0],f[y][1]);
 		f[x][1]+=f[y][0];
	 }
 }
 int main(){ 
    int i,x,y,rt=1;
    cin>>n;
    for(i=1;i<=n;i++) cin>>f[i][1];
    
    for(i=1;i<n;i++){
    	cin>>x>>y,g[y].push_back(x);
    	vis[x]=1;
	}
	while(vis[rt]) rt++;
	dp(rt);
	cout<<max(f[rt][0],f[rt][1]);
 }
 
 
 

 

 

2. 树的重心(找一个点x ,去掉x后的最大联通块最小

 

 同样任选一个点作为根

 答案= max{   max{ size(son[y] ) }  ,  n-size(x) } ,        y是x的儿子

#include <iostream>
#include <vector>
using namespace std ;
 const int N=100;
 vector<vector<int> > g(N);
 int sz[N],f[N],n;
 void dfs(int x){
 	sz[x]=1;
 	int mx=0;
 	for(int i=0;i<g[x].size();i++){
 		int y=g[x][i];
 		dfs(y);
 		sz[x]+=sz[y];
 		mx=max(mx,sz[y]);
	} 
	f[x]=max(n-sz[x],mx);
 }
 int main(){
 	int i,x,y,ans=1<<30;
 	cin>>n;
 	for(i=1;i<n;i++){
    	cin>>x>>y,g[x].push_back(y);
	}
	dfs(1);
	for(i=1;i<=n;i++){
		if(f[i]<ans) ans=f[i],x=i;
	}
	printf("%d %d\n",x,ans);
 }
 

 

3.树上最长路径

 

(1) dp

形状应该为两条路径集于一个根节点

 记录 d1[x] , d2[x] ,x子树的最长路径最大值和次大值

对所有 i :取最大值

ans =max{ d1[i]+d2[i]  }

 

 

复制代码
int d1[N],d2[N];
    
     void dp(int x,int fa){
         int i;
        for(i=0;i<g[x].size();i++){
            int y=g[x][i]; if(y==fa)continue;
            dp(y,x);
             if(d1[y]+1>=d1[x]) d2[x]=d1[x],d1[x]=d1[y]+1;
             else if(d1[y]+1>d2[x]) d2[x]=d1[y]+1;
        }
     }
复制代码

 

(2) 两次DFS

 

 参考 Luogu《巡逻》  https://www.luogu.com.cn/record/51209908

posted on   towboat  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示