• BZOJ2815: [ZJOI2012]灾难


    支配树太好写了。支配树的内容建议看原论文

    #include<bits/stdc++.h>
    #define FOR(v,a)
    	for(int v##0=0,v=0;v##0<a.size()&&((v=a[v##0])||1);++v##0)
    using namespace std;
    const int N=65536;
    vector<int>t1[N],t2[N],buc[N];
    int n,f[N],par[N],semi[N],ver[N],dom[N],anc[N],lab[N];
    void dfs(int u){
    	semi[u]=++n;
    	ver[n]=u;
    	FOR(v,t1[u]){
    		if(!semi[v]){
    			par[v]=u;
    			dfs(v);
    		}
    		t2[v].push_back(u);
    	}
    }
    int eval(int u){
    	if(anc[anc[u]]){
    		eval(anc[u]);
    		if(semi[lab[anc[u]]]<semi[lab[u]])
    			lab[u]=lab[anc[u]];
    		anc[u]=anc[anc[u]];
    	}
    	return lab[u];
    }
    void sol(int r){
    	dfs(r);
    	for(int i=1;i<=n;++i)
    		lab[i]=i;
    	for(int i=n;i>=2;--i){
    		int u=ver[i];
    		FOR(v,t2[u]){
    			int w=eval(v);
    			if(semi[w]<semi[u])
    				semi[u]=semi[w];
    		}
    		buc[ver[semi[u]]].push_back(u);
    		anc[u]=par[u];
    		FOR(v,buc[par[u]]){
    			int w=eval(v);
    			dom[v]=semi[w]<semi[v]?w:par[u];
    		}
    		buc[par[u]].clear();
    	}
    	for(int i=2;i<=n;++i){
    		int u=ver[i];
    		if(dom[u]!=ver[semi[u]])
    			dom[u]=dom[dom[u]];
    	}
    }
    int main(){
    	struct{
    		operator int(){
    			int x=0,c=getchar();
    			while(c<48)
    				c=getchar();
    			while(c>47)
    				x=x*10+c-48,c=getchar();
    			return x;
    		}
    	}buf;
    	int r=buf+1;
    	for(int u=1;u<r;++u){
    		int v=buf;
    		if(!v)
    			t1[r].push_back(u);
    		else
    			do
    				t1[v].push_back(u);
    			while(v=buf);
    	}
    	sol(r);
    	for(int i=n;i>=2;--i)
    		f[dom[ver[i]]]+=f[ver[i]]+1;
    	for(int u=1;u<r;++u)
    		printf("%d
    ",f[u]);
    }
    
  • 相关阅读:
    获取html页面传递过来的参数
    jqueryWeiui+pagehelper滚动加载(实现分页)
    【JS】js随笔
    【Java】Java基础
    【FrameWork】Hibernate
    【FrameWork】Struts2
    去掉inline-block间的间隙
    javascript单例模式
    关于call/apply与bind的一点误解
    git笔记-常用命令
  • 原文地址:https://www.cnblogs.com/f321dd/p/5496250.html
Copyright © 2020-2023  润新知