ccc 2016 s3

原创 2016年08月30日 23:24:45
/* 
把选中的点和它们的lca标记一下,然后考虑标记的点组成的这棵树。答案是:路径长度和 * 2 - 直径
想办法把选中的点和连接它们的点和边弄出来重新建棵树
以一个选中的点作为根,然后dfs,对每一个非选中的点,根据子树是否有选中的点来决定它是否要选
复杂度为 O(n)
*/ 
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;

int n, m;
const int maxn = 100000 + 5;
vector<int> g[maxn];
bool node[maxn], vis[maxn];

bool dfs(int i) {
	vis[i] = true;
	for (int k = 0; k < g[i].size(); k++) {
		int t = g[i][k]; 
		if (!vis[t] && dfs(t)) {
			node[i] = true;
		}
	}
	return node[i];
}

int dist(int i) {
	vis[i] = true;
	int temp = 0;
	for (int k = 0; k < g[i].size(); k ++ ) {
		int t = g[i][k];
		if (!vis[t] && node[t]) {
			temp += dist(t) + 1;
		}
	}
	return temp;
}

struct p {
	int num, dis;
	p(int aa, int bb) : num(aa), dis(bb) {}
};

int diameter(int i) {
	queue<int> q;
	q.push(i);
	vis[i] = true;
	int last;
	while (!q.empty()) {
		int k = q.front(); q.pop(); last = k;
		for (int w = 0; w < g[k].size(); w++) {
			int c_node = g[k][w];
			if (!vis[c_node] && node[c_node]) {
				q.push(c_node); vis[c_node] = true;
			}
		}
	}
	memset(vis, false, sizeof(vis));
	queue<p> Q;
	Q.push(p(last, 0)); vis[last] = true;
	int ans = 0;
	while (!Q.empty()) {
		p k = Q.front(); Q.pop(); ans = k.dis;
		for (int w = 0; w < g[k.num].size(); w++) {
			int c_node = g[k.num][w];
			if (!vis[c_node] && node[c_node]) {
				Q.push(p(c_node, k.dis + 1)); vis[c_node] = true;
			}
		}
	}
	return ans;
}

void solve() {
	memset(vis, false, sizeof(vis));
	int i;
	for (i = 0; i < n; i ++ ) if (node[i]) break;
	dfs(i);
	
	memset(vis, false, sizeof(vis));
	int d1 = dist(i);
	
	memset(vis, false, sizeof(vis));
	int d2 = diameter(i);
	
	printf("%d\n", 2 * d1 - d2);
}

void init() {
	memset(node, false, sizeof(node));
	scanf("%d%d", &n, &m);
	for (int i = 0; i < m; i ++ ) {
		int a; scanf("%d", &a); node[a] = true;
	}
	for (int i = 0; i < n; i ++ ) g[i].clear();
	for (int i = 1; i <= n - 1; i++) {
		int a, b; scanf("%d%d", &a, &b);
		g[a].push_back(b); g[b].push_back(a);
	}
}

int main() {
	init(); solve();
	return 0;
} 

相关文章推荐

深入理解uboot 2016 - 基础篇(S3C2410 与S5PV210处理器启动流程分析)

转载自kernel_yx     链接地址:http://blog.csdn.net/kernel_yx/article/details/53146103 S3C2440和S5PV210...

深入理解uboot 2016 - 基础篇(S3C2410 与S5PV210处理器启动流程分析)

S3C2440和S5PV210是很多嵌入式爱好者入门的arm处理器,网上的资料也很多。今天我们就来聊聊S3C2440和S5PV210的启动流程,上一篇博客我介绍了uboot在norflah上的启动流程...

3c(ccc)-中文标准,了解一下

  • 2010年03月16日 13:12
  • 643KB
  • 下载

S3F8S45 开发文档

  • 2017年11月08日 13:41
  • 2.73MB
  • 下载

使用JLink间接烧写s3c6410 nand_flash的方法

s3c6410对nand_flash的烧写功能,有些公司已经提供了SD卡的方法。但是我们也可以使用JLink把我们的uboot等程序以下面的方式烧写到我们的nand_flash上    硬件环境:...
  • xgbing
  • xgbing
  • 2012年06月17日 07:02
  • 5233

S3C2440开发资料(全)

  • 2017年11月02日 21:25
  • 9.95MB
  • 下载

S3C2410中文手册全集

  • 2016年05月17日 23:07
  • 3.3MB
  • 下载

S3C2440看门狗定时器(Watchdog)

http://blog.csdn.net/mr_raptor/article/details/6555704 ++++++++++++++++++++++++++++++++++++++++++ ...

S3C2410芯片LED历程

  • 2016年06月18日 20:16
  • 555KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ccc 2016 s3
举报原因:
原因补充:

(最多只允许输入30个字)