1. 程式人生 > >HDU 5923 Prediction(2016 CCPC東北地區大學生程序設計競賽 Problem B)

HDU 5923 Prediction(2016 CCPC東北地區大學生程序設計競賽 Problem B)

== hdu acm .cn pos ear memset long push

題目鏈接 2016 CCPC東北地區大學生程序設計競賽 B題

題意 給定一個無向圖和一棵樹,樹上的每個結點對應無向圖中的一條邊,現在給出$q$個詢問,

   每次選定樹中的一個點集,然後真正被選上的是這些點以及這些點的所有祖先。

   只有標號在樹中真正被選上的點代表的這些原圖中的邊是存在的,這樣就構成了一個新的圖。求這個圖的連通塊個數。

dfs整棵樹,記$f[x]$為若$x$以及$x$的所有祖先被選上,那麽構成的新的圖的並查集)

這個實現比較簡單,搜索的時候打上標記,回來的時候撤銷即可。

這樣預處理的時間復雜度是$O(nm)$的。

然後對於每個詢問,把$k$個詢問的並查集全部合並就可以了。

時間復雜度$O(nm + ∑kn)$

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)
#define MP		make_pair
#define fi		first
#define se		second


typedef long long LL;

const int N = 523;
const int M = 1e4 + 10;

int T;
int ca = 0;
int n, m, q;
int ans;
int a[M], b[M], c[N], f[M][N];
int father[N];
vector <int> g[M];

int getfather(int x){
	return father[x] == x ? x : father[x] = getfather(father[x]);
}

void dfs(int x, int fa){
	rep(i, 1, n) father[i] = f[fa][i];
	int fx = getfather(a[x]);
	int fy = getfather(b[x]);
	father[fx] = fy;
	rep(i, 1, n) father[i] = getfather(i);
	rep(i, 1, n) f[x][i] = father[i];
	for (auto u : g[x]){
		dfs(u, x);
	}
}

int main(){

	scanf("%d", &T);
	while (T--){
		printf("Case #%d:\n", ++ca);
		scanf("%d%d", &n, &m);
		rep(i, 0, m + 1) g[i].clear();

		rep(i, 2, m){
			int x;
			scanf("%d", &x);
			g[x].push_back(i);
		}

		memset(a, 0, sizeof a);
		memset(b, 0, sizeof b);
		rep(i, 1, m){
			scanf("%d%d", a + i, b + i);
		}

		rep(i, 1, n) f[0][i] = i;
		dfs(1, 0);

		scanf("%d", &q);
		while (q--){
			int y;
			scanf("%d", &y);
			rep(i, 1, n) father[i] = i;
			rep(i, 1, y){
				int x;
				scanf("%d", &x);
				memset(c, 0, sizeof c);
				rep(j, 1, n){
					int now = f[x][j];
					if (c[now]){
						int fx = getfather(c[now]);
						int fy = getfather(j);
						father[fx] = fy;
					}
					c[now] = j;
				}
			}

			ans = 0;
			memset(c, 0, sizeof c);
			rep(i, 1, n){
				int x = getfather(i);
				if (!c[x]) ++ans;
				c[x] = 1;
			}
			printf("%d\n", ans);
		}
	}

	return 0;
}

  

HDU 5923 Prediction(2016 CCPC東北地區大學生程序設計競賽 Problem B)