• HDU 6035


    /*
    HDU 6035 - Colorful Tree [ DFS,分块 ]
    题意:
    	n个节点的树,每个节点有一种颜色(1~n),一条路径的权值是这条路上不同的颜色的数量,问所有路径(n*(n-1)/2条) 权值之和是多少?
    分析:
    	考虑单种颜色,这种颜色的贡献是 至少经过一次这种颜色的路径数 = 总路径数(n*(n-1)/2) - 没有经过这种颜色的路径数
    	求没有经过这种颜色的路径数,即这种颜色的点将整棵树分块,每个分块中的总路径数
    */
    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    const int N = 200005;
    struct Edge {
    	int to, next;
    }edge[N<<1];
    int tot, head[N];
    void init() {
    	memset(head, -1, sizeof(head));
    	tot = 0;
    }
    void addedge(int u, int v) {
    	edge[tot].to = v; edge[tot].next = head[u];
    	head[u] = tot++;
    }
    int n;
    int c[N], last[N], rem[N], cut[N];
    LL ans;
    LL sum2(LL x) {
    	return x*(x-1)/2;
    }
    int dfs(int u, int pre)
    {
    	int su = 1, fa = last[c[u]];
    	last[c[u]] = u;
    	for (int i = head[u]; i != -1; i = edge[i].next)
    	{
    		int v = edge[i].to;
    		if (v == pre) continue;
    		cut[u] = 0;
    		int sv = dfs(v, u);
    		su += sv;
    		ans -= sum2(sv-cut[u]);
    	}
    	(fa ? cut[fa] : rem[c[u]]) += su;
    	last[c[u]] = fa;
    	return su;
    }
    int main()
    {
    	int tt = 0;
    	while (~scanf("%d", &n))
    	{
    		init();
    		for (int i = 1; i <= n; i++) scanf("%d", &c[i]);
    		for (int i = 1; i < n; i++)
    		{
    			int x, y; scanf("%d%d", &x, &y);
    			addedge(x, y); addedge(y, x);
    		}
    		memset(last, 0, sizeof(last));
    		memset(cut, 0, sizeof(cut));
    		memset(rem, 0, sizeof(rem));
    		ans = n*sum2(n);
    		dfs(1, 1);
    		for (int i = 1; i <= n; i++)
    			ans -= sum2(n-rem[i]);
    		printf("Case #%d: %lld
    ", ++tt, ans);
    	}
    }
    //----------------------------------------------------------------------
    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    const int N = 200005;
    vector<int> c[N], G[N];
    int n;
    int L[N], R[N], s[N], f[N];
    void dfs(int u, int pre, int&& ncnt)
    {
    	f[u] = pre;
    	L[u] = ++ncnt;
    	s[u] = 1;
    	for (auto& v : G[u])
    	{
    		if (v == pre) continue;
    		dfs(v, u, move(ncnt));
    		s[u] += s[v];
    	}
    	R[u] = ncnt;
    }
    bool cmp(int a, int b) {
    	return L[a] < L[b];
    }
    int main()
    {
    	int tt = 0;
    	while (~scanf("%d", &n))
    	{
    		for (int i = 0; i <= n; i++) c[i].clear(), G[i].clear();
    		for (int i = 1; i <= n; i++)
    		{
    			int x; scanf("%d", &x);
    			c[x].push_back(i);
    		} 
    		for (int i = 1; i < n; i++)
    		{
    			int x, y; scanf("%d%d", &x, &y);
    			G[x].push_back(y);
    			G[y].push_back(x); 
    		}
    		G[0].push_back(1); 
    		dfs(0, 0, 0);
    		LL ans = (LL)n * n * (n-1)/2;
    		for (int i = 1; i <= n; i++)
    		{
    			if (c[i].empty()) {
    				ans -= (LL)n*(n-1)/2;
    				continue;
    			}
    			c[i].push_back(0);
    			sort(c[i].begin(), c[i].end(), cmp);
     			for (auto& x : c[i]) 
    				for (auto& y : G[x]) 
    				{
    					if (y == f[x]) continue;
    					int size = s[y];
    					int k = L[y];
    					while (1) 
    					{
    						L[n+1] = k;
    						auto it = lower_bound(c[i].begin(), c[i].end(), n+1, cmp);
    						if (it == c[i].end() || L[*it] > R[y]) break;
    						size -= s[*it];
    						k = R[*it]+1; 
    					}
    					ans -= (LL)size * (size-1)/2;
    				}
    		}
    		printf("Case #%d: %lld
    ", ++tt, ans);
    	}
    }
    

      

    我自倾杯,君且随意
  • 相关阅读:
    Caused by: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
    jauery加入项目中,但是在页面中显示没有找到这个文件--springMVC框架
    SpringMVC中Controller和RestController
    firefox与chrome中对select下拉框中的option支持问题
    Spring与jsp表达式的产生的问题
    javaScript基础练习题-下拉框制作(神奇的代码)
    javaScript基础练习题-下拉框制作(JQuery)
    云,git,blog,感想
    javaScript基础练习题-下拉框制作(CSS)
    javaScript基础练习题-下拉框制作
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/7247361.html
Copyright © 2020-2023  润新知