[codeforces/edu2]总结(F)

链接:http://codeforces.com/contest/600

A题:

  字符串处理。

B题:

  sort+upper_bound

C题:

  统计一下每种字符的个数,然后贪心。

  (1) 如果没有奇数个的字母。直接按字典序放。

  (2) 如果有1个奇数个的字母。就把单出来的那一个字符(注意是一个字符,不是所有的那种字母)放中间,其他的按字典序放。

  (3) 如果多与1个奇数个的字母。就把单出来的每种字母的一个按字典序排好,最右边的替换成最左边的,次右边的替换成次左边的……最后情况会转变为(1)或者(2)。

D题:

  计算几何看来必须得用最科学的方法去计算啊……不然真的是卡精度卡到死。原则:能用整数决不用小数,简单题自己推别用板子。

E题:

  map+启发式合并。对于每个节点,维护两个map:M1和M2,分别表示这个子树里面颜色->个数的映射和个数->颜色的和的映射。合并的时候启发式一下就可以了,swap两个map是O(1)的。

#include<bits/stdc++.h>
using namespace std;

const int maxn=100005;
vector<int> G[maxn];
int c[maxn];
map<int,int> M[maxn];
map<int,long long> M2[maxn];
long long res[maxn];

void dfs(int u,int fa)
{
    for (int i=0;i<(int)G[u].size();i++)
    {
        int v=G[u][i];
        if (v==fa) continue;
        dfs(v,u);
        if (M[u].size()<M[v].size())
        {
            swap(M[u],M[v]);
            swap(M2[u],M2[v]);
        }
        for (auto it=M[v].begin();it!=M[v].end();++it)
        {
            int c=it->first;
            M2[u][M[u][c]]-=c;
            M[u][c]+=it->second;
            M2[u][M[u][c]]+=c;
        }
    }
    res[u]=M2[u].rbegin()->second;
}

int main()
{
    int n;
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%d",&c[i]);
    for (int i=1;i<=n-1;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for (int i=1;i<=n;i++) M[i][c[i]]=1;
    for (int i=1;i<=n;i++) M2[i][1]=c[i];
    dfs(1,-1);
    for (int i=1;i<=n;i++) printf("%I64d ",res[i]);
    return 0;
}
problem E

F题:

  题意:给一个二分图,求给边的最少染色数,要求有公共点的边不能同色。输出染色方案。

  用增广链构造……不是很懂(待补)

posted @ 2017-11-07 10:57  ACMsong  阅读(154)  评论(0编辑  收藏  举报