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;
}

浙公网安备 33010602011771号