洛谷P1041 传染病控制
标签
- 搜索
前言
- 我的csdn和博客园是同步的,欢迎来访danzh-博客园~
简明题意
- 有一棵根为1的树,每次会向儿子传播病毒。现在你可以在每次传播前切断一条路径,问最少会有多少节点感染病毒。
思路
- 首先,我们发现传播的过程就是bfs。显然,每次发的决策存在于每层的bfs中。那么就对每一层的bfs进行dfs就行了。
- 每次取出队列里的所有结点,然后将他们的儿子全部放进一个vector中。那么的决策就是从vector中切断一条,假设vector的大小是size,那么就将size-1个节点放进vector中,然后进入下一层递归。
注意事项
- 无
总结
AC代码
#include<cstdio>
#include<string>
#include<queue>
#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 300 + 10;
const int dir[8][2] = { 1, 2, 1, -2, -1, 2, -1, -2, 2, 1, 2, -1, -2, 1, -2, -1 };
int n, k;
vector<int> g[maxn], g1[maxn];
queue<int> que;
int ans = 1e9;
void dfs1(int u, int fa)
{
for (auto& it : g[u])
if (it != fa)
g1[u].push_back(it), dfs1(it, u);
}
void dfs(int sum)
{
vector<int> a;
while (!que.empty())
{
for (auto& it : g1[que.front()])
a.push_back(it);
que.pop();
}
if (a.empty())
{
ans = min(ans, sum);
return;
}
for (int i = 0; i < a.size(); i++)//删第i个
{
for (int j = 0; j < a.size(); j++)
if (j != i)
que.push(a[j]);
dfs(sum + que.size());
}
}
void solve()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
g[u].push_back(v), g[v].push_back(u);
}
dfs1(1, 1);
que.push(1);
dfs(1);
printf("%d", ans);
}
void test()
{
for (int i = 0; i <= 20; i++)
{
long long a = 1;
for (int j = 20 - i + 1; j <= 20; j++)
a *= j;
for (int j = 1; j <= i; j++)
a /= j;
printf("%d -- %lld\n", i, a);
}
}
int main()
{
freopen("Testin.txt", "r", stdin);
solve();
//test();
return 0;
}