Infección viral

Enlace: https://ac.nowcoder.com/acm/contest/11371/B
Fuente: Niuke

El título describe
que clccle y rqy estaban caminando por las calles de cierto país un día, pero el rqy ingenioso descubrió que los peatones alrededor no estaban del todo bien. Murmuraron palabras y dijeron "sqn tql!", Mientras caminaban sin rumbo fijo, clccle también Después de descubrir esto, se sorprendieron al descubrir que este extraño virus se propagará a las ciudades circundantes y eventualmente infectará a todo el país. Debido a que Internet se ha derrumbado, se han olvidado de su ciudad. Lo único que saben es que el virus es de La ciudad actual donde se encuentran ha comenzado a extenderse, y la distancia entre todas las ciudades de este país y esta ciudad es la más pequeña (la distancia entre todas las carreteras es 1), ahora le damos un mapa de todo el país, por favor ayude a rqy y Clccle encuentra en qué ciudad de este país pueden estar ahora.
Ingrese la descripción:
dos números enteros n, m, que representan que hay n ciudades en este país y solo m carreteras entre las ciudades

En las siguientes m líneas, dos enteros a, b en cada línea representan una carretera conectada entre las ciudades ay b.
Descripción de la salida:
varios enteros, generan los puntos posibles donde se encuentran actualmente clccle y rqy.
Ejemplo 1
Entrada
Copia
2 1
1 2
Salida
Copia
1 2
Observaciones:
Para todos los datos, 1 <= m <= n <= 50000

(El tipo de gráfico garantiza que no haya anillo con un tamaño mayor o igual a 3)

树形dp求出每个点到所有点的距离和,树形dp即可,关键是讨论出来父亲
对孩子的贡献,和孩子对父亲的贡献
第一次dfs的时候从下向上传递 , 此时dp[u]表示u点到子树中所有
点的最短距离之和 , x节点对当前节点的贡献是 dp[x] + size[x] , 其
含义在孩子节点x的基础上面,所有的子节点全部深度全部加一 ,
 也就是 + size[x]
 从上到下传递的时候,当前节点u对孩子节点的贡献是 dp[u] - dp[x]
  - size[x] + size[u] - size[x] ,解释: 先将当前节点的dp[u] 剪掉 所
  - 要传孩子节点x的dp[x] 贡献删掉, 根据第一步 , 其贡献是dp[x]
  -  + size[x] , size[u] 要减掉size[x] , 这两个dp[u] - dp[x] - size[x] , 和
  -  size[u] - size[x] , 都相当于在下传贡献的时候, 先将孩子节点的
  - 贡献删掉 , 然后将孩子节点数量改变一下,因为下一次x节点就变
  - 成了根节点 , dp值要变, size孩子节点也要变, 之后要用到


En términos generales, es muy necesario mantener el tamaño del nodo en el árbol dp. Si se discute la contribución del nodo hijo al nodo padre, la información del nodo hijo generalmente se obtiene de forma recursiva, y luego la contribución del nodo hijo al nodo padre y al padre Cuando un nodo contribuye a un nodo hijo, primero mantiene la información del nodo padre y luego busca la información del nodo hijo.

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <ext/rope>
#include <bits/stdc++.h> 

using namespace std;

#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)

const int mod = 1e9 + 7;

inline int read(int out = 0)
{
    
    
    char c;
    while((c=getchar()) < 48 || c > 57);
    while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
    return out; 
}

const int N = 500010;
const int M = 1e6 + 10;

int n, m;
int h[N], e[N], ne[N], idx;
int f[N], size1[N];

void add(int a, int b){
    
    
	e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

void dfs(int u, int father){
    
    
	size1[u] = 1;
	for (int i = h[u]; ~i; i = ne[i]){
    
    
		int j = e[i];
		if (j == father)   continue;
		dfs(j, u);
		size1[u] += size1[j];
		f[u] += (f[j] + size1[j]);
	}
}

void dfs1(int u, int father, int sum, int res){
    
    
	size1[u] += res;
	f[u] += sum;
	
	for (int i = h[u]; ~i; i = ne[i]){
    
    
		int j = e[i];
		if (j == father)   continue;
		dfs1(j, u, f[u] - f[j] - 2 * size1[j] + size1[u], size1[u] - size1[j]);
	}
}

signed main(){
    
    
	ios;
	
	gt(n), gt(m);
	memset(h, -1, sizeof h);
	
	while(m --){
    
    
		int a, b;
		gt(a), gt(b);
		add(a, b), add(b, a);
	}
	
	dfs(1, -1);
	dfs1(1, -1, 0, 0);
	
	int ans = 0x7f7f7f7f;
	
	for (int i = 1; i <= n; i ++){
    
    
		ans = min(ans, f[i]);
	}
	
	for (int i = 1; i <= n; i ++){
    
    
		if (f[i] == ans){
    
    
			cout << i << " ";
		}
	}
	cout << endl;
	
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_45772483/article/details/112638939
Recomendado
Clasificación