zoukankan      html  css  js  c++  java
  • CF1156D 0-1-Tree

    路径考虑顺序。

    显然合法的路径只有以下两种:

    1. 一段 (0) 加一段 (1) 或一段 (1) 加一段 (0)
    2. (0) 或全 (1)

    用并查集将边权为 (0)(1) 的边分别缩起来,对于一个大小为 (siz) 的联通块,第二种的答案是 (siz(siz-1))

    对于第一种,我们枚举 (0)(1) 的分界点,它所在 (0)(1) 的联通块大小分别是 (siz_0)(siz_1),它的答案是 ((siz_0-1)(siz_1-1))

    然后这题就做完了,时间复杂度 (O(nalpha(n)))

    code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define N 2
    #define NN 200005
    #define For(i,x,y)for(i=x;i<=(y);i++)
    int fa[NN][N],siz[NN][N];
    int read()
    {
    	int A;
    	bool K;
    	char C;
    	C=A=K=0;
    	while(C<'0'||C>'9')K|=C=='-',C=getchar();
    	while(C>'/'&&C<':')A=(A<<3)+(A<<1)+(C^48),C=getchar();
    	return(K?-A:A);
    }
    int find(int p,bool type)
    {
    	if(fa[p][type]!=p)fa[p][type]=find(fa[p][type],type);
    	return fa[p][type];
    }
    inline void unite(int p,int q,bool type)
    {
    	p=find(p,type),q=find(q,type);
    	if(p==q)return;
    	if(siz[p][type]<siz[q][type])fa[p][type]=q,siz[q][type]+=siz[p][type];
    	else fa[q][type]=p,siz[p][type]+=siz[q][type];
    }
    int main()
    {
    	bool c;
    	ll ans=0;
    	int n,i,x,y;
    	n=read();
    	For(i,1,n)fa[i][0]=fa[i][1]=i,siz[i][0]=siz[i][1]=1;
    	For(i,1,n-1)
    	{
    		x=read(),y=read(),c=read();
    		unite(x,y,c);
    	}
    	For(i,1,n)ans+=1LL*(siz[find(i,0)][0]-1)*(siz[find(i,1)][1]-1);
    	For(i,1,n)
    	{
    		ans+=1LL*siz[find(i,0)][0]*(siz[find(i,0)][0]-1)+1LL*siz[find(i,1)][1]*(siz[find(i,1)][1]-1);
    		siz[find(i,0)][0]=siz[find(i,1)][1]=0;
    	}
    	cout<<ans;
    	return 0;
    }
    
  • 相关阅读:
    [转]WebService 之 WSDL文件 讲解
    WebService代理类的详解
    Net 多语言
    Net缓存使用
    分布式缓存的一些想法
    关于webdriver中弹出框的定位
    关于Autoit上传文件的问题
    webdriver中定位元素,报无法找到元素的问题
    java.net.SocketException: Software caused connection abort: socket write error
    接口测试之soupui&groovy
  • 原文地址:https://www.cnblogs.com/May-2nd/p/13832550.html
Copyright © 2011-2022 走看看