CodeForces - 796D:Police Stations

题目链接:CodeForces - 796D
题目描述

Inzane finally found Zane with a lot of money to spare, so they together decided to establish a country of their own.


Ruling a country is not an easy job. Thieves and terrorists are always ready to ruin the country’s peace. To fight back, Zane and Inzane have enacted a very effective law: from each city it must be possible to reach a police station by traveling at most d kilometers along the roads.


There are n cities in the country, numbered from 1 to n, connected only by exactly n - 1 roads. All roads are 1 kilometer long. It is initially possible to travel from a city to any other city using these roads. The country also has k police stations located in some cities. In particular, the city’s structure satisfies the requirement enforced by the previously mentioned law. Also note that there can be multiple police stations in one city.


However, Zane feels like having as many as n - 1 roads is unnecessary. The country is having financial issues, so it wants to minimize the road maintenance cost by shutting down as many roads as possible.


Help Zane find the maximum number of roads that can be shut down without breaking the law. Also, help him determine such roads.

输入

The first line contains three integers n, k, and d (2 ≤ n ≤ 3·105, 1 ≤ k ≤ 3·105, 0 ≤ d ≤ n - 1) — the number of cities, the number of police stations, and the distance limitation in kilometers, respectively.


The second line contains k integers p1, p2, …, pk (1 ≤ pi ≤ n) — each denoting the city each police station is located in.


The i-th of the following n - 1 lines contains two integers ui and vi (1 ≤ ui, vi ≤ n, ui ≠ vi) — the cities directly connected by the road with index i.


It is guaranteed that it is possible to travel from one city to any other city using only the roads. Also, it is possible from any city to reach a police station within d kilometers.

输出

In the first line, print one integer s that denotes the maximum number of roads that can be shut down.


In the second line, print s distinct integers, the indices of such roads, in any order.


If there are multiple answers, print any of them.

题目大意:
一共有n个结点,由n-1条边连接,每条边长度为1。总共有k个特殊结点,它们分布在指定位置(与之前n中的结点重合),要求最多去掉几条边,仍然可以保证每个结点到最近的特殊结点的距离小于等于d.

思路:
1)同C题,n个结点n-1条边,不存在环。每个结点到它最近的特殊结点只有唯一的路径。
2)如果删除某一条边,则形成两棵树,每一棵树至少要有一个特殊结点,所以答案小于等于k-1。
3)对于每一个普通结点,把它加入到离它最近的特殊结点形成的树中。
4)对每一个特殊结点进行一次广度优先搜索,如果存在普通结点已被标记过,则此边可以删除。

CODE:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef pair<int,int> pai;
int n,k,d,ans;
const int MAXN=3e5+10;
queue<pai> que;
vector<pai> wire[MAXN];
int vis[MAXN];
int flag[MAXN];
void BFS()
{
	while(!que.empty())
	{
		int f=que.front().first;
		int t=que.front().second;
		que.pop();
		if(vis[f])continue;
		vis[f]=1;
		for(int i=0;i<wire[f].size();i++)
		{
			int v=wire[f][i].first;
			int num=wire[f][i].second;
			if(v!=t)
			{
				if(vis[v])flag[num]=1,ans++;
				else que.push(pai(v,f));
			}
		}
	}
}
void init()
{
	ans=0;
	for(int i=1;i<=n;i++)wire[i].clear();
	while(!que.empty())que.pop();
	memset(vis,0,sizeof(vis));
	memset(flag,0,sizeof(flag));
}
int main()
{
	while(~scanf("%d %d %d",&n,&k,&d))
	{
		int f,t;
		init();
		for(int i=1;i<=k;++i)
		{
			scanf("%d",&f);
			que.push(pai(f,0));
		}
		for(int i=1;i<=n-1;i++)
		{
			scanf("%d %d",&f,&t);
			wire[f].push_back(pai(t,i));
			wire[t].push_back(pai(f,i));
		}
		BFS();
		printf("%d\n",ans);
		for(int i=1;i<=n-1;++i)
			if(flag[i])printf("%d ",i);	
		printf("\n");		
	}	
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/weixin_43843835/article/details/85015386