求助,40pts,搜索+贪心
查看原帖
求助,40pts,搜索+贪心
66097
tjhdyhj楼主2023/10/24 18:02

思路:搜出当前所有可能导致感染的路中会导致后续感染最多的路,并将其下行结点标记。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#define MAXN 314
using namespace std;
int N,M,head[MAXN],cnt=1,ans,note[MAXN];
struct nodee{
	int u,v,next,tot;
}f[MAXN*2];
void add(int u,int v)
{
	cnt++;
	f[cnt].u=u;
	f[cnt].v=v;
	f[cnt].next=head[u];
	head[u]=cnt;
}
void dfs1(int p,int in_edge)
{
	int u,i,tot=1;
	for (i=head[p];i;i=f[i].next)
	{
		if (i!=(in_edge^1))
		{
			dfs1(f[i].v,i);
			tot+=f[i].tot;
		}
	}
	f[in_edge].tot=f[(in_edge^1)].tot=tot;
}
void dfs2()
{
	int i,j,rem=0;
	queue<int> p;
	p.push(1);
	while (!p.empty())
	{
		int maxn=0,maxm=0;
		int L=p.size();
		for (i=0;i<L;i++)
		{
			int u=p.front();
			p.pop();
			p.push(u);
			for (j=head[u];j;j=f[j].next)
				if (f[j].tot>maxn&&note[f[j].v]!=1)
					{
					maxn=f[j].tot;
					maxm=f[j].v;
					}
		}
		ans-=maxn;
		rem=maxm;
		for (i=0;i<L;i++)
		{
			int u=p.front();
			p.pop();
			note[u]=1;
			if (u!=rem)
				for (j=head[u];j;j=f[j].next)
					if (note[f[j].v]!=1)
						p.push(f[j].v);
		}
	}
}
int main()
{
	int i,j,a1,a2;
	cin>>N>>M;
	ans=N;
	for (i=1;i<=M;i++)
	{
		cin>>a1>>a2;
		add(a1,a2);
		add(a2,a1);
	}
	dfs1(1,0);
	dfs2();
	cout<<ans;
	return 0;
}
2023/10/24 18:02
加载中...