zoukankan      html  css  js  c++  java
  • 「SCOI2005」王室联邦

    「SCOI2005」王室联邦

    传送门
    树分块。
    考虑把树,按照节点个数每 (B) 个分块,把块顶作为省会。
    这是具体证明
    参考代码:

    #include <cstdio>
    #define rg register
    #define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
    using namespace std;
    template < class T > inline void read(T& s) {
    	s = 0; int f = 0; char c = getchar();
    	while ('0' > c || c > '9') f |= c == '-', c = getchar();
    	while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
    	s = f ? -s : s;
    }
    
    const int _ = 1010;
    
    int tot, head[_], nxt[_ << 1], ver[_ << 1];
    inline void Add_edge(int u, int v)
    { nxt[++tot] = head[u], head[u] = tot, ver[tot] = v; }
    
    int n, B, cnt, num, rt[_], bel[_], x[_];
    
    inline void dfs(int u, int f) {
    	int tmp = num;
    	for (rg int i = head[u]; i; i = nxt[i]) {
    		int v = ver[i]; if (v == f) continue;
    		dfs(v, u);
    		if (num - tmp >= B) {
    			rt[++cnt] = u;
    			while (num > tmp) bel[x[num--]] = cnt;
    		}
    	}
    	x[++num] = u;
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
    	file("cpp");
    #endif
    	read(n), read(B);
    	for (rg int u, v, i = 1; i < n; ++i)
    		read(u), read(v), Add_edge(u, v), Add_edge(v, u);
    	dfs(1, 0);
    	if (!cnt) rt[++cnt] = 1;
    	while (num) bel[x[num--]] = cnt;
    	printf("%d
    ", cnt);
    	for (rg int i = 1; i <= n; ++i) printf("%d%c", bel[i], " 
    "[i == n]);
    	for (rg int i = 1; i <= cnt; ++i) printf("%d%c", rt[i], " 
    "[i == n]);
    	return 0;
    }
    
  • 相关阅读:
    sql 内链接
    使用python 写一个自动windows桌面壁纸的程序
    在windows使用pyinstall 打包 flask 再使用nsis软件打包成安装包
    超微主板ibm密码
    jenkins邮件模板
    gp集群常用命令
    shell小知识
    Linux配置免密
    文件基础命令
    华为初识命令
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/12231578.html
Copyright © 2011-2022 走看看