P6111 [USACO18JAN] MooTube S

P6111 [USACO18JAN] MooTube S

Insira a descrição da imagem aqui

Formato de saída

Saída de linhas Q Na linha i, responda à i-ésima pergunta de FJ.

Entrada e saída de amostra

Entrada

4 3
1 2 3
2 3 2
2 4 4
1 2
4 1
3 1

Saída

3
0
2

Idéia:
se a pergunta K tiver apenas um valor e depois encontrar o número recomendado de vídeos para cada ponto, é simples.

Mas a dificuldade é que K é uma variável. Justamente quando quero arranhar meu couro cabeludo, acho que Luo Gu tem um problema .

No começo, para cada par de pontos, quero adicionar o peso da aresta conectada entre esses dois pontos a K ou mais. Mas ainda é uma pergunta antiga, K é uma variável!

Primeiro, classificamos o problema pelo valor K (descendente) e, em seguida, classificamos cada aresta pelo peso da aresta (descendente)
porque, para uma aresta, se você tiver um valor K grande, poderá encontrá-lo e, em seguida, pode ser pequeno, ou seja: Não afeta os resultados subsequentes, um pouco como a ineficiência da programação dinâmica.
Em seguida, é realmente uma questão de adicionar lados.
De acordo com o significado da pergunta, você não pode se recomendar; portanto, a resposta é -1 (-ele mesmo).

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=5e3+10;
int n,qu,f[N],num[N],ans[N];
struct node
{
	int u,v,w;
}edge[N];
struct node1
{
	int id,k,v;
}q[N];
int find(int x) {return x==f[x]?x:f[x]=find(f[x]);}
void unionn(int x,int y)
{
	int a=find(x),b=find(y);
	if(a!=b) f[a]=b,num[b]+=num[a];  //num[i]为父节点i所连满足条件的边数 
}
bool cmp1(node x,node y){return x.w>y.w;}
bool cmp2(node1 x,node1 y){return x.k>y.k;}
void input()
{
	scanf("%d%d",&n,&qu);
	for(int i=1;i<=n;i++) f[i]=i,num[i]=1;
	for(int i=1;i<n;i++)  scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
	for(int i=1;i<=qu;i++) scanf("%d%d",&q[i].k,&q[i].v),q[i].id=i;
}
void work()
{
	sort(edge+1,edge+n,cmp1);
	sort(q+1,q+qu+1,cmp2);
	int j=1;
	for(int i=1;i<=qu;i++)
	{
		while(edge[j].w>=q[i].k&&j<n) unionn(edge[j].u,edge[j].v),j++;
		ans[q[i].id]=num[find(q[i].v)]-1;  
		//这里不要写成num[q[i].v],你是在个集合里面,所以要找集合中的老大才知道有多少成员 
	}
	for(int i=1;i<=qu;i++) printf("%d\n",ans[i]);
}
int main()
{
	//fre();
	input();
	work();
	return 0;
}
Publicado 130 artigos originais · Gosto 93 · Visitantes 6792

Acho que você gosta

Origin blog.csdn.net/bigwinner888/article/details/105601110
Recomendado
Clasificación