HXY烧情侣

Posted kanchuang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HXY烧情侣相关的知识,希望对你有一定的参考价值。

题目描述

众所周知,HXY已经加入了FFF团。现在她要开始喜(sang)闻(xin)乐(bing)见(kuang)地烧情侣了。这里有n座电影院,n对情侣分别在每座电影院里,然后电影院里都有汽油,但是要使用它需要一定的费用。m条单向通道连接相邻的两对情侣所在电影院。然后HXY有个绝技,如果她能从一个点开始烧,最后回到这个点,那么烧这条回路上的情侣的费用只需要该点的汽油费即可。并且每对情侣只需烧一遍,电影院可以重复去。然后她想花尽可能少的费用烧掉所有的情侣。问最少需要多少费用,并且当费用最少时的方案数是多少?由于方案数可能过大,所以请输出方案数对1e9+7取模的结果。

(注:这里HXY每次可以从任何一个点开始走回路。就是说一个回路走完了,下一个开始位置可以任选。所以说不存在烧不了所有情侣的情况,即使图不连通,HXY自行选择顶点进行烧情侣行动。且走过的道路可以重复走。)

输入输出格式

输入格式:

第一行,一个整数n。

第二行,n个整数,表示n个情侣所在点的汽油费。

第三行,一个整数m。

接下来m行,每行两个整数xi,yi,表示从点xi可以走到yi。

输出格式:

一行,两个整数,第一个数是最少费用,第二个数是最少费用时的方案数对1e9+7取模

输入输出样例

输入样例#1: 
3
1 2 3
3
1 2
2 3
3 2
输出样例#1: 
3 1
输入样例#2: 
3
10 20 10
4
1 2
1 3
3 1
2 1
输出样例#2: 
10 2

说明

数据范围:

对于30%的数据,1<=n,m<=20;

对于10%的数据,保证不存在回路。

对于100%的数据,1<=n<=100000,1<=m<=300000。所有输入数据保证不超过10^9。

 

闲话:

烧情侣???记得带我一个啊!

 

分析:

本题题面中的走回路告诉了我们这题的算法:缩点!至于答案我们可以开一个数组进行存储,最后统一求解。

 

CODE:

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 const int M=2222222;
 8 const int MOD=1000000007;
 9 int n,m,tot,cnt,k;
10 int vis[M],low[M],maxn[M],dfn[M],to[M],head[M],nxt[M],v[M],connected[M],stack[M],ways[M];
11 void add(int u,int v)
12     nxt[++tot]=head[u];head[u]=tot;
13     to[tot]=v;return;
14 
15 void tarjan(int x)
16     low[x]=dfn[x]=++tot;vis[x]=1;stack[++stack[0]]=x;
17     for (int i=head[x];i;i=nxt[i])
18         if (!dfn[to[i]])
19             tarjan(to[i]);
20             low[x]=min(low[x],low[to[i]]);
21         
22         else if (vis[to[i]]) low[x]=min(low[x],dfn[to[i]]);
23     
24     if (low[x]==dfn[x])
25         maxn[++k]=2000000000;
26         while (stack[stack[0]]!=x)
27             connected[stack[stack[0]]]=k;vis[stack[stack[0]]]=0;
28             maxn[k]=min(maxn[k],v[stack[stack[0]]]);
29             stack[0]--;
30         
31         connected[stack[stack[0]]]=k;maxn[k]=min(maxn[k],v[stack[stack[0]]]);
32         vis[stack[stack[0]]]=0;stack[0]--;
33     
34     return;
35 
36 int fr()
37     int ans=0,f=1;
38     char c=getchar();
39     while (c<0||c>9)if (c==-) f=-1;c=getchar();
40     while (c>=0&&c<=9)ans=(ans<<1)+(ans<<3)+(c^48);c=getchar();
41     if (f) return ans;return -ans;
42 
43 int main()
44     n=fr();
45     for (int i=1;i<=n;i++) v[i]=fr();
46     m=fr();
47     for (int i=1;i<=m;i++)
48         int x=fr(),y=fr();
49         add(x,y);
50     
51     long long ans=0;
52     for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i);
53     for (int i=1;i<=k;i++) ans+=maxn[i];
54     cout<<ans<<" ";ans=1;
55     for (int i=1;i<=n;i++)
56         if (v[i]==maxn[connected[i]]) ways[connected[i]]++;
57     for (int i=1;i<=k;i++) ans=ans*ways[i]%MOD;
58     cout<<ans;
59     return 0;
60 

 

以上是关于HXY烧情侣的主要内容,如果未能解决你的问题,请参考以下文章

HXY烧情侣(洛谷 2194)

P2194 HXY烧情侣

HXY烧情侣

洛谷 P2194 HXY烧情侣Tarjan缩点 分析+题解代码

P2194 HXY烧情侣Tarjan

洛谷 P2194 HXY烧情侣