首页 > 代码库 > [luoguP1041] 传染病控制(DFS)

[luoguP1041] 传染病控制(DFS)

传送门

 

n <= 300

结果裸的dfs就直接过了。。

枚举每一层,枚举删除每一层的边,然后把删除的边所连接的子树全部删去

 

代码

#include <vector>#include <cstdio>#include <cstring> #include <iostream>#define N 301#define min(x, y) ((x) < (y) ? (x) : (y))#define max(x, y) ((x) > (y) ? (x) : (y))int n, m, cnt, maxd, ans = ~(1 << 31);int head[N], to[N << 1], next[N << 1], f[N], deep[N], size[N];std::vector <int> vec[N];bool vis[N];inline int read(){	int x = 0, f = 1;	char ch = getchar();	for(; !isdigit(ch); ch = getchar()) if(ch == ‘-‘) f = -1;	for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - ‘0‘;	return x * f;}inline void add(int x, int y){	to[cnt] = y;	next[cnt] = head[x];	head[x] = cnt++;}inline void dfs(int u){	int i, v;	size[u] = 1;	maxd = max(maxd, deep[u] = deep[f[u]] + 1);	vec[deep[u]].push_back(u);	for(i = head[u]; i ^ -1; i = next[i])	{		v = to[i];		if(v ^ f[u])		{			f[v] = u;			dfs(v);			size[u] += size[v];		}	}}inline void dfs2(int u, int x){	int i, v;	vis[u] = x;	for(i = head[u]; i ^ -1; i = next[i])	{		v = to[i];		if(v ^ f[u]) dfs2(v, x);	}}inline void dfs1(int k, int sum){	ans = min(ans, n - sum);	if(k == maxd + 1) return;	int i, x;	for(i = 0; i < vec[k].size(); i++)	{		x = vec[k][i];		if(!vis[x])		{			dfs2(x, 1);			dfs1(k + 1, sum + size[x]);			dfs2(x, 0);		}	}}int main(){	int i, x, y;	n = read();	m = read();	memset(head, -1, sizeof(head));	for(i = 1; i <= m; i++)	{		x = read();		y = read();		add(x, y);		add(y, x);	}	dfs(1);	dfs1(2, 0);	printf("%d\n", ans);	return 0;}

  

[luoguP1041] 传染病控制(DFS)