社区讨论
30分 DFS求救。。
P1041[NOIP 2003 提高组] 传染病控制(疑似错题)参与者 4已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @mi7utle8
- 此快照首次捕获于
- 2025/11/21 03:58 4 个月前
- 此快照最后确认于
- 2025/11/21 03:58 4 个月前
简单思路就是每次枚举砍掉的子树,然后走其他的, 同时统计救活的人数,最后输出
n-救活人数就可以了。dfs1来维护数组S,S[i]表示以i为结点的结点个数
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <cmath>
using namespace std;
const int _ = 610;
int S[_];
struct Edge{
int node;
int nxt;
}G[_];
int head[_];
int tot = 0;
inline void add(int u, int v)
{
G[++tot].nxt = head[u];
G[tot].node = v;
head[u] = tot;
G[++tot].nxt = head[v];
G[tot].node = u;
head[v] = tot;
}
int n;
bool vis[_];
int dfs1(int nowNode)
{
if(vis[nowNode]) return 0;
vis[nowNode] = true;
// printf("at Node:%d\n", nowNode);
int Sum = 1;
for(register int i = head[nowNode];i;i = G[i].nxt)
Sum += dfs1(G[i].node);
return S[nowNode] = Sum;
}
int Sum = 0;
int Max = 0;
void dfs2(int nowNode, int father)
{
// printf("Node at %d \n", nowNode);
if(!G[head[nowNode]].nxt)
{
// cout<< Sum<<endl;
Max = max(Max, Sum);
return ;
}
for(register int i = head[nowNode];i;i = G[i].nxt)
{
if(G[i].node == father) continue;
Sum += S[ G[i].node ];
// printf("Give up node %d\n", G[i].node);
for(register int j = head[nowNode];j;j = G[j].nxt)
{
if(i == j || G[j].node == father)continue;
dfs2(G[j].node, nowNode);
}
Sum -= S[ G[i].node ];
}
}
int main()
{
int m;
scanf("%d%d", &n, &m);
for(register int i = 1;i <= m;i++)
{
int tx, ty;
scanf("%d%d", &tx, &ty);
add(tx, ty);
}
memset(vis, false, sizeof(vis));
dfs1(1);
// for(register int i = 1;i <= n;i++)
// {
// printf("node %d have %d sons\n", i, S[i]);
// }
dfs2(1, -1);
printf("%d", n - Max);
// system("pause");
return 0;
}
/*
7 6
1 2
1 3
2 4
2 5
3 6
3 7
*/
回复
共 3 条回复,欢迎继续交流。
正在加载回复...