题解 CF427C 【Checkposts】

VenusM1nT

2020-11-26 21:37:21

Solution

这波啊,这波是绿题上紫。 观察到是单向图,直接大力缩点,每个点的贡献就是点内权值最小的那个,加起来就得到了第一问的答案。记录一下每个点里有多少个贡献最小的,乘法原理乘起来一搞就出来了。 ```cpp #include<bits/stdc++.h> #define N 100000 #define reg register #define inl inline using namespace std; const int Mod=1e9+7; int n,m,a[N+5],dfn[N+5],low[N+5],idx,bel[N+5],tot,siz[N+5],minx[N+5]; bool ins[N+5]; vector <int> g[N+5]; stack <int> s; void Tarjan(reg int u) { dfn[u]=low[u]=++idx; s.push(u); ins[u]=1; for(auto v : g[u]) { if(!dfn[v]) { Tarjan(v); low[u]=min(low[u],low[v]); } else if(ins[v]) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { reg int v=0; tot++; while(u!=v) { v=s.top(); s.pop(); bel[v]=tot; ins[v]=0; } } } int main() { scanf("%d",&n); for(reg int i=1;i<=n;i++) scanf("%d",&a[i]); scanf("%d",&m); for(reg int i=1;i<=m;i++) { reg int x,y; scanf("%d %d",&x,&y); g[x].push_back(y); } for(reg int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i); memset(minx,60,sizeof(minx)); for(reg int i=1;i<=n;i++) minx[bel[i]]=min(minx[bel[i]],a[i]); reg long long ans=0,Ans=1; for(reg int i=1;i<=n;i++) if(minx[bel[i]]==a[i]) siz[bel[i]]++; for(reg int i=1;i<=tot;i++) ans=ans+minx[i],Ans=Ans*1ll*siz[i]%Mod; printf("%lld\n%lld\n",ans,Ans); return 0; } ```