Solution - P2194 HXY烧情侣

FXY 烧情侣(什么鬼)

思路

乘法原理都会吧。

缩点求 min,然后把 min 的数量乘起来就可以啦。不难。

注意和不需要膜 \(10^9+7\)

代码

#include <bits/stdc++.h>
#define rint register int
#define rllong register long long
#define llong long long
#define N 100005
#define M 300005
using namespace std;

constexpr int mod = 1e9+7;
int to[M], nxt[M], head[N], gsiz = 1;
#define mkarc(u,v) (++gsiz, to[gsiz]=v, nxt[gsiz]=head[u], head[u]=gsiz)
int dfn[N], low[N], dfcnt;
int belong[N], minn[N], cnt[N], n2;
int sta[N], top;
int a[N];
int n, m;
llong sum, ans = 1;

inline void tarjan(rint u){
	dfn[u] = low[u] = ++dfcnt;
	sta[++top] = u;
	for(rint i = head[u]; i; i = nxt[i]){
		rint v = to[i];
		if(!dfn[v]){
			tarjan(v);
			low[u] = min(low[u], low[v]);
		}
		else if(!belong[v]) low[u] = min(low[u], dfn[v]);
	}
	if(dfn[u] == low[u]){
		++n2, minn[n2] = 1e9+7;
		while(sta[top+1] != u){
			rint now = sta[top--];
			belong[now] = n2;
			if(a[now] < minn[n2])
				minn[n2] = a[now], cnt[n2] = 1;
			else if(a[now] == minn[n2])
				++cnt[n2];
		}			
	}
	return;
}

int main(){
	scanf("%d", &n);
	for(rint i = 1; i <= n; ++i) scanf("%d", &a[i]);
	scanf("%d", &m);
	for(rint i = 1; i <= m; ++i){
		rint u, v;
		scanf("%d %d", &u, &v);
		mkarc(u, v);
	}
	for(rint i = 1; i <= n; ++i)
		if(!dfn[i]) tarjan(i);
	for(rint i = 1; i <= n2; ++i)
		sum = sum+minn[i], ans = ans*cnt[i]%mod;
	printf("%lld %lld", sum, ans);
	return 0;
}

posted @ 2025-05-14 17:23  Hootime  阅读(14)  评论(0)    收藏  举报