zoukankan      html  css  js  c++  java
  • HDU 4303 Contest 1

    说实话,挺复杂的一道题。

    我采用栈的方式,DFS在搜索完一个节点的所有子结点后,通过排序,加快计算该结点所有可能的路径:子结点与子结点的连通,子结点与父结点的连通,通过父结点与各祖先结点的连通。同时记录路径数计算。思路清晰就能写出来了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define LL __int64
    const int N=300010;
    using namespace std;
    
    struct e{
    	int u,v;
    	int col;
    	int next;
    }edge[N*2];
    int head[N];
    int tot;
    int val[N];
    struct p{
    	LL valsum;
    	LL route;
    	int col;
    }DFST[N],pre,aft;
    LL tmp;
    
    void addedge(int u,int v,int col){
    	edge[tot].u=u;
    	edge[tot].v=v;
    	edge[tot].col=col;
    	edge[tot].next=head[u];
    	head[u]=tot++;
    	edge[tot].u=v;
    	edge[tot].v=u;
    	edge[tot].col=col;
    	edge[tot].next=head[v];
    	head[v]=tot++;
    }
    
    bool cmp(p a, p b){
    	if(a.col<b.col) return true;
    	return false;
    }
    
    void dfs(LL &ans,int parent,int now,int parent_col,LL &route,int pos){
    	int k=-1; LL son_val,son_route;
    	for(int ei=head[now];ei!=-1;ei=edge[ei].next){
    		if(edge[ei].v==parent) continue;
    		k++; son_val=son_route=0;
    		dfs(son_val,now,edge[ei].v,edge[ei].col,son_route,pos+k);
    		DFST[pos+k].valsum=son_val; DFST[pos+k].route=son_route; 
    		DFST[pos+k].col=edge[ei].col;
    	}
    	if(k>=0){
    		sort(DFST+pos,DFST+pos+k+1,cmp);
    		for(int i=0;i<=k;i++){
    			if(parent!=-1)
    				tmp+=((LL)DFST[pos+i].valsum+(LL)val[now]*DFST[pos+i].route);
    			if(DFST[pos+i].col!=parent_col){
    				ans+=((LL)DFST[pos+i].valsum+(LL)val[now]*DFST[pos+i].route);
    				route+=(LL)DFST[pos+i].route;
    			}
    		}
    		if(parent!=-1){
    			ans+=val[now];
    			route++;
    		}
    		if(DFST[pos+k].col!=DFST[pos].col){
    			pre=DFST[pos];
    			int c=DFST[pos].col;
    			for(int i=1;i<=k;i++){
    				if(DFST[pos+i].col==c){
    					pre.valsum=pre.valsum+DFST[pos+i].valsum;
    					pre.route=pre.route+DFST[pos+i].route;
    				}
    				else{
    					aft=DFST[pos+i];
    					int si=i+1;
    					while(aft.col==DFST[pos+si].col&&si<=k){
    						aft.valsum+=DFST[pos+si].valsum;
    						aft.route+=DFST[pos+si].route;
    						si++;
    					}
    					i=si-1;
    					tmp+=(pre.route*aft.valsum+aft.route*pre.valsum+(pre.route*aft.route)*val[now]);
    					pre.route+=aft.route;
    					pre.valsum+=aft.valsum;
    					c=aft.col;
    				}
    			}
    		}
    	}
    	else{
    		ans=val[now];
    		route=1;
    	}
    }
    
    int main(){
    	int n,u,v,c;
    	while(scanf("%d",&n)!=EOF){
    		tmp=0;
    		for(int i=1;i<=n;i++)
    		scanf("%d",&val[i]);
    		memset(head,-1,sizeof(head));
    		tot=0;
    		for(int i=1;i<n;i++){
    			scanf("%d%d%d",&u,&v,&c);
    			addedge(u,v,c);
    		}
    		LL ans=0,route=0;
    		dfs(ans,-1,1,-1,route,0);//sum,parent,nownode,parent_col,route,beginpos
    		printf("%I64d
    ",ans+tmp);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    txtbox取Calendar值
    【Spread Sheet 应用(一)】去掉原有功能键及添加功能键
    【SQLSERVER】存储过程基础
    【SQLSERVER】在存储过程中调用存储过程
    ASP.NET跨页面传值技巧(VB.NET篇)
    【EXCEL】IF...ELSE语句
    VB单元测试
    【VB.NET】窗体之间传值
    【Spread Sheet 应用(二)】常用属性设置
    【SQLSERCER】创建、改变、删除索引
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4049041.html
Copyright © 2011-2022 走看看