zoukankan      html  css  js  c++  java
  • 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]);
    }
    
  • 相关阅读:
    List sort()方法
    解析器
    beautifulsoup库
    break 语句
    enumerate函数
    POJ 1915 Knight Moves
    POJ 1745 Divisibility
    POJ 1731 Orders
    POJ 1664 放苹果
    POJ 1606 Jugs
  • 原文地址:https://www.cnblogs.com/f321dd/p/5496250.html
Copyright © 2011-2022 走看看