HDU 6832 A Very Easy Graph Problem (Minimum Spanning Tree+dfs)

Meaning of the question: Insert picture description here
Solution: The minimum spanning tree + dfs
input edge weight is larger than the previously input edge weight sum. According to the input, use kruskal to find mst.

We have guaranteed the shortest. Since the sum of all the paths from 1 to 0 is required, we can find out how many 0s and 1s are after each edge through dfs, and record with the dp array. The total after subtraction is the previous one, according to the principle of multiplication Just do the math.

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
using namespace std;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 5;
int t, n, m, a[maxn], u, v, f[maxn], dp[maxn][2], n0, n1;
ll ans;
vector<pair<int, int> > g[maxn];
void dfs(int u, int pre) {
    
    
	dp[u][a[u]]++;
	for (auto i : g[u]) {
    
    
		if (i.first == pre) continue;
		dfs(i.first, u);
		dp[u][0] += dp[i.first][0];
		dp[u][1] += dp[i.first][1];
	}
	for (auto i : g[u]) {
    
    
		if (i.first == pre) continue;
		ans = (ans + 1ll * dp[i.first][0] * (n1 - dp[i.first][1]) % mod * i.second % mod) % mod;
		ans = (ans + 1ll * dp[i.first][1] * (n0 - dp[i.first][0]) % mod * i.second % mod) % mod;
	}
}
int Find(int x) {
    
    
	return x == f[x] ? x : f[x] = Find(f[x]);
}
int main() {
    
    
	scanf("%d", &t);
	while (t--) {
    
    
		ans = n0 = n1 = 0;
		scanf("%d%d", &n, &m);
		for (int i = 1; i <= n; i++) {
    
    
			scanf("%d", &a[i]);
			if (a[i]) n1++;
			else n0++;
		}
		for (int i = 1; i <= n; i++) g[i].clear(), dp[i][0] = dp[i][1] = 0, f[i] = i;
		int x = 1;
		for (int i = 1; i <= m; i++) {
    
    
			scanf("%d%d", &u, &v);
			int pu = Find(u);
			int pv = Find(v);
			if (pu == pv) continue;
			f[pu] = pv;
			x = 1ll * x * 2 % mod;
			g[u].push_back(make_pair(v, x));
			g[v].push_back(make_pair(u, x));
		}
		dfs(1, -1);
		printf("%lld\n", ans);
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_43680965/article/details/107857363