JZOJ 6838. [2020.10.31 Improved group simulation] The combination of small j (the diameter of the tree)

JZOJ 6838. [2020.10.31 Improve group simulation] The combination of small j

Topic

  • Give an initial size of nnThe tree of n can be operated as follows:
  • Choose one choose one point vvv , add another pointv ′ v'v ,Change v ′ v'v Connect to all andvvv Connected points.
  • Seeking the minimum number of operations and the scheme makes a Hamiltonian loop exist in the graph.
  • n ≤ 100 n\leq 100 n100

answer

  • The Hamiltonian loop needs to pass each point once and only once, unless it is a chain, it does not exist on the tree.
  • It can be found that the operation is equivalent to copying each point once, which is equivalent to allowing this point to pass one more time. With this conclusion, it is much easier.
  • In the tree DFS, you need to operate once every time you return to the father, but this does not guarantee the least operation (of course, you do not need to return to the root node in the end)
  • The points that do not need to be returned form a chain, and each remaining point needs to be returned once. Obviously, when the chain is the longest, that is, the diameter, the number of operations is the least.
  • Just find the diameter simulation directly.

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 110
int dis[N][N], p[N];
int ans[N * 2], sum, n;
void dfs(int k, int t) {
    
    
	int x = 0;
	ans[++ans[0]] = k, p[k] = 1;
	for(int i = 1; i <= n; i++) if(dis[k][i] == 1 && !p[i]) {
    
    
		if(dis[t][i] + 1 == dis[t][k]) {
    
    
			x = i;
			continue;
		}
		dfs(i, t);
		printf("%d ", k);
		ans[++ans[0]] = ++sum;
	}
	if(x) dfs(x, t);
}
int main() {
    
    
	int i, j, k, x, y;
	scanf("%d", &n);
	for(i = 1; i <= n; i++)
		for(j = 1; j <= n; j++) if(i == j) dis[i][j] = 0; else dis[i][j] = N;
	for(i = 1; i < n; i++) {
    
    
		scanf("%d%d", &x, &y);
		dis[x][y] = dis[y][x] = 1;
	}	
	for(k = 1; k <= n; k++)
		for(i = 1; i <= n; i++)
			for(j = 1; j <= n; j++) dis[i][j] = min(dis[i][k] + dis[j][k], dis[i][j]);
	int s = 1, t = 1;
	for(i = 1; i <= n; i++)
	 	for(j = 1; j <= n; j++) if(dis[i][j] > dis[s][t]) s = i, t = j;
	printf("%d\n", n - dis[s][t] - 1);
	sum = n;
	dfs(s, t);
	printf("\n");
	for(i = 1; i <= ans[0]; i++) printf("%d ", ans[i]);
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_39565901/article/details/109412482