【拓扑】【堆】【DFS】我的世界

L i n k Link Link

l u o g u   T 145121 luogu\ T145121 luogu T145121

D e s c r i p t i o n Description Description

【拓扑】【堆】【DFS】我的世界_第1张图片
在这里插入图片描述

S a m p l e Sample Sample I n p u t Input Input

4 
3 1
1 2 
4 2

S a m p l e Sample Sample O u t p u t Output Output

3 2 4 1

H i n t Hint Hint

【拓扑】【堆】【DFS】我的世界_第2张图片

S o l u t i o n Solution Solution

其实很好发现,肯定是点之间两两配对才行,那么我们从叶子节点出发,与它父亲配对,然后将这两个点标记,然后继续弄
然后再将配对的点与其他点连边啥的,得到一个图,再搞一下拓扑排序,用堆维护,每次取最小编号就好了

C o d e Code Code

#include 
#include
#include
#include

using namespace std;
priority_queue< int,vector<int>,greater<int> >d;

int t, n, e, tt;
int ans[500005], ru[500005];
int hh[500005], h[500005], link[500005];

int read() 
{
	int x = 0, flag = 1; char ch = getchar();
	while (ch < '0' || ch > '9') {if (ch == '-') flag = -1; ch = getchar();}
	while (ch >= '0' && ch <= '9'){x = x * 10 + ch - '0'; ch = getchar();}
	return x * flag;
}

void write(int x)
{
    if (x < 0) { 
		x = -x; 
		putchar('-');
	}
	if (x > 9) write(x / 10);
	putchar(x % 10 + 48);
	return;
}

struct node
{
	int to, next;
}w[1000005];

struct nodex
{
	int to, next;
}p[1000005];

void addx(int x, int y)
{p[++e] = (nodex){y, hh[x]}; hh[x] = e;}

void add(int x, int y)
{
	w[++t] = (node){y, h[x]}; h[x] = t;
	w[++t] = (node){x, h[y]}; h[y] = t;
}

void build(int x, int fath)
{
	for (int i = h[x]; i; i = w[i].next)
		if (w[i].to != fath) build(w[i].to, x);
	if (link[fath] || link[x]) return;
	link[x] = fath; link[fath] = x;
	for (int i = h[fath]; i; i = w[i].next)
		if (w[i].to != x) 
			ru[w[i].to]++, addx(x, w[i].to);
	for (int i = h[x]; i; i = w[i].next)
		if (w[i].to != fath)
			ru[w[i].to]++, addx(fath, w[i].to);
}

int main()
{
	n = read();
	if (n % 2) {printf("-1"); return 0;}
	for (int i = 1; i < n; ++i)
	{
		int u, v;
		u = read(); v = read();
		add(u, v);
	}
	build(1, 0);
	for (int i = 1; i <= n; ++i)
		if (!link[i]) {
			putchar('-');
			putchar('1');
			return 0;
		}
	for (int i = 1; i <= n; ++i)
		if (!ru[i]) d.push(i);
	for (int i = 1; i <= n; ++i)
	{
		ans[i] = d.top();
		d.pop();
		for (int k = hh[ans[i]]; k; k = p[k].next)
		{
			ru[p[k].to]--;
			if (!ru[p[k].to]) 
				d.push(p[k].to);
		}
	}
	for (int i = 1; i <= n; ++i)
		write(ans[i]), putchar(' ');
	return 0;
}

你可能感兴趣的:(堆,dfs,dfs,堆)