【BZOJ5109】【CodePlus2017】大吉大利,晚上吃鸡!

【题目链接】

【思路要点】

  • 补档博客,无题解。

【代码】

#include<bits/stdc++.h>
using namespace std;
#define MAXN	50005
#define INF	1e18
#define P	1000000007
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
struct info {long long value; int pos; };
bool operator < (info a, info b) {return a.value > b.value; }
int n, m, s, t;
int x[MAXN], y[MAXN], z[MAXN];
vector <int> a[MAXN];
vector <int> b[MAXN];
priority_queue <info> Heap;
long long dist[MAXN];
bool finished[MAXN];
bitset <MAXN> seta[MAXN], setb[MAXN];
map <int, bitset <MAXN> > f;
long long cnta[MAXN], cntb[MAXN];
void worka(int pos) {
	cnta[pos] = (pos == t);
	seta[pos].set(pos);
	if (pos == t) return;
	for (unsigned i = 0; i < a[pos].size(); i++) {
		worka(a[pos][i]);
		cnta[pos] += cnta[a[pos][i]];
		cnta[pos] %= P;
		if (cnta[a[pos][i]]) seta[pos] |= seta[a[pos][i]];
	}
}
void workb(int pos) {
	cntb[pos] = (pos == s);
	setb[pos].set(pos);
	if (pos == s) return;
	for (unsigned i = 0; i < b[pos].size(); i++) {
		workb(b[pos][i]);
		cntb[pos] += cntb[b[pos][i]];
		cntb[pos] %= P;
		if (cntb[b[pos][i]]) setb[pos] |= setb[b[pos][i]];
	}
}
int main() {
	read(n), read(m), read(s), read(t);
	for (int i = 1; i <= m; i++) {
		read(x[i]), read(y[i]), read(z[i]);
		if (z[i] == 0) continue;
		a[x[i]].push_back(y[i]);
		a[y[i]].push_back(x[i]);
		b[x[i]].push_back(z[i]);
		b[y[i]].push_back(z[i]);
	}
	for (int i = 1; i <= n; i++)
		dist[i] = INF;
	dist[s] = 0;
	Heap.push((info) {0, s});
	while (!Heap.empty()) {
		while (!Heap.empty() && finished[Heap.top().pos])
			Heap.pop();
		if (Heap.empty()) break;
		info tmp = Heap.top();
		Heap.pop();
		for (unsigned i = 0; i < a[tmp.pos].size(); i++)
			if (tmp.value + b[tmp.pos][i] < dist[a[tmp.pos][i]]) {
				dist[a[tmp.pos][i]] = tmp.value + b[tmp.pos][i];
				Heap.push((info) {dist[a[tmp.pos][i]], a[tmp.pos][i]});
			}
	}
	for (int i = 1; i <= n; i++)
		a[i].clear();
	for (int i = 1; i <= n; i++)
		b[i].clear();
	for (int i = 1; i <= m; i++) {
		if (z[i] == 0) continue;
		if (dist[x[i]] + z[i] == dist[y[i]]) a[x[i]].push_back(y[i]), b[y[i]].push_back(x[i]);
		if (dist[y[i]] + z[i] == dist[x[i]]) a[y[i]].push_back(x[i]), b[x[i]].push_back(y[i]);
	}
	worka(s);
	workb(t);
	for (int i = 1; i <= n; i++) {
		cnta[i] = cnta[i] * cntb[i] % P;
		seta[i] |= setb[i];
		seta[i].set(i);
		f[cnta[i]].set(i);
	}
	long long ans = 0;
	for (int i = 1; i <= n; i++) {
		int tmp = (cnta[t] - cnta[i] + P) % P;
		ans += (f[tmp] & (~seta[i])).count();
	}
	cout << ans / 2 << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39972971/article/details/80685137
今日推荐