[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; }
F题:
题意:给一个二分图,求给边的最少染色数,要求有公共点的边不能同色。输出染色方案。
用增广链构造……不是很懂(待补)