题解 P3629 【[APIO2010]巡逻】

luogu

分析

luogu需要一篇vector题解
好吧我承认我代码写得有些冗长
k=1时,求树的直径长度记为L1,输出2(n-1)-L1+1;
k=2时,将k=1时的直径经过的边的权值记为-1,再求一遍树的直径记为L2,输出2
n-L1-L2。

Code

#include<bits/stdc++.h>
using namespace std;
struct Node
{
	int x,y;
};
int n,k,vis[200010],fa[200010],Dis[200010],X,XX,f[200010],ans=-0x7FFFFFFF;
int ip1,ip2;
vector<int>a[200010];
int Get_len()
{
	int res=0;
	queue<Node>q;
	q.push(Node{1,0});
	memset(vis,0,sizeof(vis));
	vis[1]=1;
	while(!q.empty())
	{
		Node t=q.front();
		q.pop();
		for(int i=0;i<a[t.x].size();i++)
		{
			if(!vis[a[t.x][i]])
			{
				vis[a[t.x][i]]=1;
				if(res<t.y+1)
				{
					res=t.y+1;
					X=a[t.x][i];
				}
				q.push(Node{a[t.x][i],t.y+1});
			}
		}
	}
	memset(vis,0,sizeof(vis));
	q.push(Node{X,0});
	vis[X]=1;
	while(!q.empty())
	{
		Node t=q.front();
		q.pop();
		for(int i=0;i<a[t.x].size();i++)
		{
			if(!vis[a[t.x][i]])
			{
				vis[a[t.x][i]]=1;
				fa[a[t.x][i]]=t.x;
				if(res<t.y+1)
				{
					res=t.y+1;
					XX=a[t.x][i];
				}
				q.push(Node{a[t.x][i],t.y+1});
			}	
		}
	}
	return res;
}
int Get_len2(int u,int FA)
{
	for(int i=0;i<a[u].size();i++)
	{
        int v=a[u][i];
        if(v==FA)
            continue;
        Get_len2(v,u);
        int temp=1;
        if(Dis[u]&&Dis[v])
            temp=-1;
        ans=max(ans,f[u]+f[v]+temp);
        f[u]=max(f[u],f[v]+temp);
    }
}
int find(int x)
{
	if(fa[x]!=X)
	{
		int N=find(fa[x]);
		Dis[N]=-1;
		Dis[x]=-1;
	}
	return x;
}
void bfs1()
{
	int ans=2*(n-1)-Get_len()+1;
	cout<<ans; 
	return;
}
void bfs2()
{
	int L1=Get_len();
	find(XX);
	Dis[X]=-1;
	int L2=Get_len2(1,0);
	cout<<2*n-L1-ans;
	return;
}
int main()
{
	cin>>n>>k;
	for(int i=1;i<n;i++)
	{
		cin>>ip1>>ip2;
		a[ip1].push_back(ip2);
		a[ip2].push_back(ip1);
	}
	if(k==1)
	{
		bfs1();
	}
	if(k==2)
	{
		bfs2();
	}
}
posted @ 2019-08-09 21:56  G_A_TS  阅读(409)  评论(0编辑  收藏  举报