zoukankan      html  css  js  c++  java
  • [六省联考2017]摧毁“树状图”

    [六省联考2017]摧毁“树状图”

    题目大意:

    给你一个(n(nle5 imes10^5))个点的图,从图中选两条链,删掉链上所有点以及所有相连的边,使得剩下的连通块数目最多,求连通块个数。

    思路:

    树形DP。

    • f[x][0]:穿过(x)向上的半条链
    • f[x][1]:不穿过(x)且完全在子树内的一条链
    • f[x][2]:穿过(x)且完全在子树内的一条链
    • f[x][3]:穿过(x)向上的半条连以及完全在子树内的一条链

    然后就是各种大力讨论。

    这个有图示的题解比较好懂。

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<vector>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    const int N=5e5+1;
    std::vector<int> e[N];
    inline void add_edge(const int &u,const int &v) {
    	e[u].push_back(v);
    	e[v].push_back(u);
    }
    int f[N][4],ans;
    inline void upd(int &a,const int &b) {
    	a=std::max(a,b);
    }
    void dfs(const int &x,const int &par) {
    	const bool isrt=x==1;
    	const int deg=e[x].size()-!isrt;
    	f[x][0]=f[x][2]=f[x][3]=deg;
    	f[x][1]=1;
    	int max=0;
    	for(unsigned i=0;i<e[x].size();i++) {
    		const int &y=e[x][i];
    		if(y==par) continue;
    		dfs(y,x);
    		upd(ans,f[x][0]+f[y][3]-isrt);
    		upd(ans,f[x][3]+f[y][0]-isrt);
    		upd(ans,f[x][1]+f[y][1]-1);
    		upd(ans,f[x][1]+f[y][2]);
    		upd(ans,f[x][2]+f[y][1]-isrt);
    		upd(ans,f[x][2]+f[y][2]-isrt);
    		upd(f[x][1],f[y][1]);
    		upd(f[x][1],f[y][2]+1);
    		upd(f[x][3],f[y][3]+deg-1);
    		upd(f[x][3],f[y][0]+max+deg-2);
    		upd(f[x][3],f[x][0]+f[y][1]-1);
    		upd(f[x][3],f[x][0]+f[y][2]-1);
    		upd(f[x][3],f[x][2]+f[y][0]-1);
    		upd(f[x][2],f[x][0]+f[y][0]-1);
    		upd(f[x][0],f[y][0]+deg-1);
    		upd(f[x][2],f[x][0]);
    		upd(f[x][3],f[x][2]);
    		upd(max,f[y][1]);
    		upd(max,f[y][2]);
    	}
    }
    int main() {
    	const int T=getint(),x=getint();
    	for(register int i=0;i<T;i++) {
    		const int n=getint();
    		for(register int i=0;i<x*2;i++) getint();
    		for(register int i=1;i<n;i++) {
    			add_edge(getint(),getint());
    		}
    		ans=0;
    		dfs(1,0);
    		printf("%d
    ",ans);
    		for(register int i=1;i<=n;i++) {
    			e[i].clear();
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    SharpReader的效率:支持meme聚合
    RSS阅读器:从订阅到发现之旅?
    关于word使用WildCards进行查找和替换
    Cannot resolve plugin org.apache.maven.plugins:mavencleanplugin:2.5
    MyBatis
    python matplotlib中axes与axis subplot的区别是什么?
    MyBatis中settings属性配置详解
    IDEA中 Project 和 Module 的区别
    Pycharm 运行程序后如何 如何查看变量的值(不通过debug的方式)
    查看oracle是否正常、表空间 (AIX)
  • 原文地址:https://www.cnblogs.com/skylee03/p/9770455.html
Copyright © 2011-2022 走看看