• CodeForces


    题目链接

    题目大意

      有一个n个点的树,每个点都有一个权值,并且父节点的权值严格大于所有子节点的权值,现在给你n个点中任意两个点的lca的权值,让你构造出来这棵树。

    解题思路

      因为父节点的权值严格大于所有子节点的权值,很容易想到按权值从小到大开始合并,但是有一个坑点,就是如果有几对点的lca的权值都一样的话,需要做一下处理。比如1,2,3,4这个四个点的lca的权值都一样,那么如果先和并1和2,再合并3和4,最后再合并这两组的话,就会出现父节点和子节点权值相等的情况,所以可以在权值都相等的时候对i排序,这样的话就是1和2,1和3,1和4这样合并,就不会有上面的问题了。

    代码

    const int maxn = 5e2+10;
    const int maxm = 3e5+10;
    int n, g[maxn][maxn], sal[maxm], p[maxm];
    int find(int x) {
    	return p[x]==x ? p[x]:p[x]=find(p[x]);
    }
    struct I {
    	int u, v, w;
    } a[maxm];
    int main() {	
    	cin >> n;
    	for (int i = 1; i<=n; ++i)
    		for (int j = 1; j<=n; ++j)
    			cin >> g[i][j];
    	int tot = 0;
    	for (int i = 1; i<=n; ++i) sal[i] = g[i][i];
    	for (int i = 1; i<=n; ++i)
    		for (int j = i+1; j<=n; ++j) 
    			a[++tot] = {i, j, g[i][j]};
    	sort(a+1, a+tot+1, [](I a, I b) {return a.w==b.w ? a.u<b.u : a.w<b.w;});
    	for (int i = 1; i<maxm; ++i) p[i] = i;
    	int num = n; vector<P> ans; 
    	for (int i = 1; i<=tot; ++i) {
    		int fa = find(a[i].u);
    		int fb = find(a[i].v);
    		if (fa!=fb) {
    			if (a[i].w>sal[fa] && a[i].w>sal[fb]) {
    				++num;
    				p[fa] = num;
    				p[fb] = num;
    				sal[num] = a[i].w;
    				ans.push_back({fa, num});
    				ans.push_back({fb, num});
    			}
    			else if (sal[fa]==a[i].w) {
    				p[fb] = fa;
    				ans.push_back({fb, fa});
    			}
    			else if (sal[fb]==a[i].w) {
    				p[fa] = fb;
    				ans.push_back({fa, fb});
    			}
    		}
    	}
    	cout << num << endl;
    	for (int i = 1; i<=num; ++i) printf(i==num ? "%d
    ":"%d ", sal[i]);
    	cout << find(1) << endl;
    	for (auto v : ans) cout << v.x << ' ' << v.y << endl;
    	return 0;	
    } 
    
    
  • 相关阅读:
    Codeforces610b
    Codeforces597A
    Timus1014(贪心算法)
    一般贪心
    优先队列问题(此题来源哈尔滨理工大学VJ)
    POJ2551Dungeon Master
    LightOJ 1140: How Many Zeroes? (数位DP)
    HDU 2089:不要62(数位DP)
    HDU 4722:Good Numbers(数位DP)
    HDU 3709: Balanced Number (数位DP)
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/14476867.html
Copyright © 2020-2023  润新知