codeforces 427C Checkposts

来源:互联网 发布:淘宝上找不到sis账号 编辑:程序博客网 时间:2024/04/30 04:11
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
 
 

Your city has n junctions. There aremone-way roads between the junctions. As a mayor of the city, you have to ensure the security of all the junctions.

To ensure the security, you have to build some police checkposts. Checkposts can only be built in a junction. A checkpost at junctioni can protect junctionj if eitheri = j or the police patrol car can go toj fromi and then come back toi.

Building checkposts costs some money. As some areas of the city are more expensive than others, building checkpost at some junctions might cost more money than other junctions.

You have to determine the minimum possible money needed to ensure the security of all the junctions. Also you have to find the number of ways to ensure the security in minimum price andin addition in minimum number of checkposts. Two ways are different if any of the junctions contains a checkpost in one of them and do not contain in the other.

Input

In the first line, you will be given an integern, number of junctions(1 ≤ n ≤ 105). In the next line,n space-separated integers will be given. Theith integer is the cost of building checkpost at theith junction (costs will be non-negative and will not exceed109).

The next line will contain an integerm (0 ≤ m ≤ 3·105). And each of the nextm lines contains two integersui andvi (1 ≤ ui, vi ≤ nu ≠ v). A pair ui, vi means, that there is a one-way road which goes fromui tovi. There will not be more than one road between two nodes in the same direction.

题目大意

给一个地图,n个点(1 ≤ n ≤ 105),m条(单向)边 (0 ≤ m ≤ 3·105)。每个点都可以在此建立一个岗哨,花费为vi。这个哨岗可以保证j节点的安全,j 满足:j = i 或者可以从 i 出发到 j ,然后还可以从 j 出发回到 i 。问如何建岗哨,使得花费最小,花费最小的方案有几种。

Output

Print two integers separated by spaces. The first one is the minimum possible money needed to ensure the security of all the junctions. And the second one is the number of ways you can ensure the security modulo 1000000007(109 + 7).

Input

31 2 331 22 33 2

Output

3 1

Input

52 8 0 6 061 41 32 43 44 55 1

Output

8 2

Input

101 3 2 2 1 3 1 4 10 10121 22 33 13 44 55 65 76 47 38 99 1010 9

Output

15 6

Input

27 9121 22 1

Output

7 1

 

题解

强连通分量,计数用乘法原理。

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<cmath>#define mod 1000000007#define inf 0x7fffffffusing namespace std;int n,m,v[100002],head[100002];struct bian {int to,nx;} e[300002];int pre[100002],low[100002],cont,scc,sccnum[100002];int minv[100002],num[100002];int stack[100002],top;long long ans,gs=1;void init(){scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&v[i]);scanf("%d",&m);for(int i=1;i<=m;i++)   {int x,y;scanf("%d%d",&x,&y);e[i].to=y; e[i].nx=head[x]; head[x]=i;   }}void dfs(int x){pre[x]=low[x]=++cont;stack[++top]=x;int i=head[x];while(i)    {int p=e[i].to; if(!pre[p]) {dfs(p); low[x]=min(low[x],low[p]);} else if(!sccnum[p]) low[x]=min(low[x],pre[p]); i=e[i].nx;}int p=-1;if(pre[x]==low[x])   {scc++; minv[scc]=inf;    while(p!=x)       {p=stack[top]; top--;    sccnum[p]=scc;     if(v[p]<minv[scc]) {minv[scc]=v[p]; num[scc]=1;}    else if(v[p]==minv[scc]) num[scc]++;   }   }}void tarjan(){for(int i=1;i<=n;i++)   {if(!pre[i]) dfs(i);}}int main(){init();tarjan();for(int i=1;i<=scc;i++)   {ans+=minv[i];gs=(gs*num[i])%mod;   }printf("%I64d %I64d",ans,gs);return 0;}

 
0 0