拓扑排序及链式前向星的应用

1593E - Gardener and Tree

题意:给出一棵树,问对其进行k次操作还剩多少个结点,
思路:建立邻接表,每次出入度为1的点,注意要进行1个节点的特判

#include<bits/stdc++.h>
using namespace std;
const int maxn = 4e5 + 10;
struct {//链式前向星
	int to;
	int next;
}edge[maxn<<1];
int tot;
int head[maxn ];
int du[maxn];
void add(int u, int v) {
	tot++;
	edge[tot].to = v;
	edge[tot].next = head[u];
	head[u] = tot;
}
int main() {
	int i, j, k, n, t;
	cin >> t;
	while (t--) {
		tot = 0;
		memset(du, 0, sizeof(du));
		memset(head, 0, sizeof(head));
		cin >> n >> k;		
			for (i = 1; i <= n - 1; i++)
			{
				int u, v;
				cin >> u >> v;
				add(u, v);
				add(v, u);
				du[u]++;
				du[v]++;
			}
			queue<int>q;int sum = 0;
			for (i = 1; i <= n; i++) {
				if (du[i] == 1) {
					q.push(i);
				}
			}
			while (k&&!q.empty()) {
				k--;
				queue<int>p;
				sum += q.size();
				while (!q.empty()) 
				{
					int u = q.front();
					q.pop();
					du[u]--;
					for (i = head[u]; i; i = edge[i].next) {
						int v = edge[i].to;
						du[v]--;
						if (du[v] == 1)//应该每次都要判定而不能最后判定,因为有些点可能入度会减到0
							p.push(v);
					}
				}
				q = p;
			}
			if (n == 1)//特判一个结点
				cout << 0 << endl;
			else
				cout << n - sum << endl;
	}
}

类似拓扑排序的模板题

posted @ 2021-11-01 18:43  spzjc  阅读(66)  评论(0)    收藏  举报