zoukankan      html  css  js  c++  java
  • 「ZJOI2014」璀灿光华

    「ZJOI2014」璀灿光华

    实际上,可以不用建水晶立方体...

    因为,发光水晶的方向都要枚举一遍。

    只需知道发光水晶每个方向有哪些水晶就可以了。

    对于一个发光水晶,将它连接的水晶标号。

    从该水晶bfs,若某水晶在相同步数下被访问过两次,那么它必然不是某一方向的直线上的(挺显然的吧)。

    每个点的标号为最先访问到它的点的标号。

    这样可以整出发光水晶每个方向的水晶。

    时间复杂度(o(n a^3))

    之后把每个发光水晶朝向枚举一遍,复杂度(o(6^n a))

    #include<bits/stdc++.h>
    #define rep(q,a,b) for(int q=a,q##_end_=b;q<=q##_end_;++q)
    #define dep(q,a,b) for(int q=a,q##_end_=b;q>=q##_end_;--q)
    #define mem(a,b) memset(a,b,sizeof a )
    #define debug(a) cerr<<#a<<' '<<a<<"___"<<endl
    using namespace std;
    void in(int &r) {
    	static char c;
    	r=0;
    	while(c=getchar(),c<48);
    	do r=(r<<1)+(r<<3)+(c^48);
    	while(c=getchar(),c>47);
    }
    const int mn=70*70*70+100;
    int n;
    vector<int> son[mn];
    vector<int> rt,ft[8][6];
    int mk[mn];
    int val[mn],que[mn],mark[mn];
    bool is_used[mn];
    int tot_val,Max,Min=1e9;
    void dfs(int x){
    	if(x==(int)rt.size()){
    		Max=max(Max,tot_val);
    		Min=min(Min,tot_val);
    		return;
    	}
    	vector<int> sta;
    	rep(q,0,5){
    		sta.clear();
    		rep(w,0,(int)ft[x][q].size()-1){
    			int y=ft[x][q][w];
    			if(!is_used[y]){
    				sta.push_back(y);
    				is_used[y]=1;
    				tot_val+=val[y];
    			}
    		}
    		dfs(x+1);
    		rep(w,0,(int)sta.size()-1)is_used[sta[w]]=0,tot_val-=val[sta[w]];
    		if(ft[x][q].size()==0)return;
    	}
    }
    int main(){
    	freopen("glitter.in","r",stdin);
    	freopen("glitter.out","w",stdout);
    	in(n);
    	char c;
    	int r;
    	rep(q,1,n*n*n){
    		in(val[q]);
    		if(!val[q])rt.push_back(q);
    		while(1){
    			r=0;
    			while(c=getchar(),c<48);
    			do r=(r<<1)+(r<<3)+(c^48);
    			while(c=getchar(),c>47);
    			son[q].push_back(r);
    			if(c=='
    '||c=='
    ')break;
    		}
    	}
    	rep(q,0,(int)rt.size()-1){
    		int l=0,r=0;
    		int now=rt[q];
    		mk[now]=-1;
    		rep(w,0,(int)son[now].size()-1)mk[son[now][w]]=w+1,mark[son[now][w]]=1,que[++r]=son[now][w];
    		while(l<r){
    			int nw=que[++l];
    			rep(w,0,(int)son[nw].size()-1){
    				int to=son[nw][w];
    				if(mk[to]==0)mk[to]=mk[nw],mark[to]=mark[nw]+1,que[++r]=to;
    				else if(mark[to]==mark[nw]+1)is_used[to]=1;
    			}
    		}
    		rep(w,1,r){
    			if(!is_used[que[w]])ft[q][mk[que[w]]-1].push_back(que[w]);
    			is_used[que[w]]=0;
    			mk[que[w]]=0,mark[que[w]]=0;
    		}
    		mk[now]=0,mark[now]=0;
    	}
    	dfs(0);
    	printf("%d %d
    ",Min,Max);
    	return 0;
    }
    
  • 相关阅读:
    Golang手动分页,按等份拆分数据
    GORM无法映射到结构体上
    VSCODE GOLANG运行多个服务
    解决,MAVEN
    Properties配置文件常见错误写法以及转义字符说明
    Pentaho Data Integration (PDI/Kettle)与Java版本支持关系
    MYSQL之读写分离搭建方案
    Windows下创建软件快速启动命令
    Sonar的一些使用总结
    使用SVG Path绘图
  • 原文地址:https://www.cnblogs.com/klauralee/p/10925648.html
Copyright © 2011-2022 走看看