前言

当时和\(GYZ\)大佬一起做这个题,他表示这个题对他很不友好(手动滑稽)

题目描述

众所周知,\(HXY\) 已经加入了 \(FFF\) 团。现在她要开始喜(sang)闻(xin)乐(bing)见(kuang)地烧情侣了。

这里有 \(n\) 座电影院,\(n\) 对情侣分别在每座电影院里,然后电影院里都有汽油,但是要使用它需要一定的费用。\(m\) 条单向通道连接相邻的两对情侣所在电影院。

\(HXY\) 有个绝技,如果她能从一个点开始烧,最后回到这个点,那么烧这条回路上的情侣的费用只需要该点的汽油费即可。并且每对情侣只需烧一遍,电影院可以重复去。然后她想花尽可能少的费用烧掉所有的情侣。

问:最少需要多少费用,并且当费用最少时的方案数是多少?由于方案数可能过大,所以请输出方案数对 \(10^9+7\)取模的结果。

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

输入格式

第一行一个正整数 \(n\)。

第二行 \(n\) 个正整数,表示每个点的汽油费 \(w_i\)。

第三行一个正整数 \(m\)。

接下来 \(m\) 行,每行两个正整数 \(x_i,y_i\) ,表示一条 \(x_i \to y_i\) 的单向道路。

输出格式

输出一行两个整数,分别表示最小花费,和花费最小时的方案数。

输入输出样例

输入 #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\le n,m \le 20\);

对于另外 \(10\%\) 的数据,保证不存在回路;

对于 \(100\%\) 的数据,\(1\le n \le 10^5\) ,\(1\le m \le 3\times 10^5\),\(1\le w_i \le 10^9\) 。

分析

看到题目中从一个点烧,可以连带烧掉这一条回路上的所有情侣,所以就是一个\(Tarjan\)缩点的问题。在缩点的时候把每个强连通分量里最小的点权记录为这一强连通分量的最小权。然后取完\(min\)之后(这里的取\(min\)是当他小于他的时候更新),下边判断一下是否相等,因为小于的时候才会更新,等于的时候不会更新,所以直接让相等的数量++。最后直接统计答案就可以了。(其实根本不用取模,到不了那么大,但是还是写上比较好)

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e5+10;
int head[maxn],low[maxn],dfn[maxn];
struct Node{
int v,next;
}e[maxn<<1];
int val[maxn];
int sum[maxn];
int rd[maxn];
int ans;
int vis[maxn],c[maxn];
int cnt1[maxn];
int tot,cnt,num,top,sta[maxn];
void Add(int x,int y){//建边
e[++tot].v = y;
e[tot].next = head[x];
head[x] = tot;
}
void Tarjan(int x){//Tarjan缩点
sta[++top] = x;
dfn[x] = low[x] = ++num;
vis[x] = 1;
for(int i=head[x];i;i = e[i].next){
int v=e[i].v;
if(!dfn[v]){
Tarjan(v);
low[x] = min(low[x],low[v]); }
else if(vis[v]){
low[x] = min(low[x],dfn[v]);
}
}//以上都是基操
if(dfn[x] == low[x]){
cnt++;
int y;
while(1){
y=sta[top--];
c[y] = cnt;
vis[y] = 0;
if(sum[cnt] > val[y]){//取最小值,等于的话不取,到下边判断
sum[cnt] = val[y];
cnt1[cnt] = 0;
}
if(sum[cnt] == val[y])cnt1[cnt]++;//等于就说明情况数,直接++
if(x == y)break;
}
}
}
int m;
int n;
int main(){
memset(val,0x3f,sizeof(val));//初始化
memset(sum,0x3f,sizeof(val));
ios::sync_with_stdio(false);//cin/cout优化
cin.tie(0);//同上一行,不用cin/cout的不用写这东西
cin>>n;
for(int i=1;i<=n;++i){
cin>>val[i];
}
cin>>m;
for(int i=1;i<=m;++i){
int x,y;
cin>>x>>y;
Add(x,y);
}
for(int i=1;i<=n;++i){
if(!dfn[i])Tarjan(i);
}
int ans1=1;
for(int i=1;i<=cnt;++i){//统计答案
ans1*=cnt1[i];//乘法计数原理统计方案数
ans+=sum[i];//统计最小花费
}
cout<<ans<<" "<<ans1<<"\n"; }

P2194 HXY烧情侣【Tarjan】的更多相关文章

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

    洛谷 P2194 HXY烧情侣[Tarjan缩点] 分析+题解代码 题目描述: 众所周知,HXY已经加入了FFF团.现在她要开始喜(sang)闻(xin)乐(bing)见(kuang)地烧情侣了.这里 ...

  2. 洛谷P2194 HXY烧情侣

    题目描述 众所周知,\(HXY\)已经加入了\(FFF\)团.现在她要开始喜\((sang)\)闻\((xin)\)乐\((bing)\)见\((kuang)\)地烧情侣了.这里有\(n\)座电影院, ...

  3. 【luogu P2194 HXY烧情侣】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2194 第一问:缩点并且统计其强连通分量里的最小耗费.把所有强连通分量的最小耗费加起来. 第二问:统计在每个强 ...

  4. luogu P2194 HXY烧情侣

    残忍的题面 我们来看这一道题,其实冗长的题目告诉我们一个核心——用tarjan tarjan是用来干什么呢?是用来求强连通分量(代码中指sc) 求出来又有什么用呢?每当我们求出一个强连通分量时,就去计 ...

  5. HXY烧情侣(洛谷 2194)

    题目描述 众所周知,HXY已经加入了FFF团.现在她要开始喜(sang)闻(xin)乐(bing)见(kuang)地烧情侣了.这里有n座电影院,n对情侣分别在每座电影院里,然后电影院里都有汽油,但是要 ...

  6. HXY烧情侣

    题目描述 众所周知,HXY已经加入了FFF团.现在她要开始喜(sang)闻(xin)乐(bing)见(kuang)地烧情侣了.这里有n座电影院,n对情侣分别在每座电影院里,然后电影院里都有汽油,但是要 ...

  7. 洛谷P2194 【HXY烧情侣】

    首先请允许我吐槽一下这个题面 这个题面透露出血腥与暴力,电影院里还藏汽油 所以情侣们,要是想看电影就在家里看吧 毕竟出来容易被烧 在家里看虽然观影效果不如在电影院里 但是, 起码咱生命安全啥的有保障啊 ...

  8. 洛谷P2194HXY烧情侣

    传送门啦 这个题可以说是tarjan强连通分量的裸题,但需要维护每个强连通分量的最小值,所以做法就很明确了. 我们先明确几个数组的意思: 1.首先是tarjan缩点中的几个数组: dfn[i]:i点的 ...

  9. Tarjan总结(缩点+割点(边)+双联通+LCA+相关模板)

    Tarjan求强连通分量 先来一波定义 强连通:有向图中A点可以到达B点,B点可以到达A点,则称为强连通 强连通分量:有向图的一个子图中,任意两个点可以相互到达,则称当前子图为图的强连通分量 强连通图 ...

随机推荐

  1. Java四种权限修饰符

    四种权限修饰符

  2. treegrid树形表格的完美运用

    一 问题描述: 树形表格TreeGrid在日常项目中还是运用的比较多的,哪我们在项目中,应该怎么引入和使用 TreeGrid呢? 二 使用步骤 1.首先我们需要在项目中,引入TreeGrid组件  需 ...

  3. Java实现 LeetCode 406 根据身高重建队列

    406. 根据身高重建队列 假设有打乱顺序的一群人站成一个队列. 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数. 编写一个算法来重建这个队列. ...

  4. Java实现 蓝桥杯VIP 算法训练 星际交流

    算法训练 星际交流 时间限制:1.0s 内存限制:256.0MB 问题描述 人类终于登上了火星的土地并且见到了神秘的火星人.人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法 ...

  5. Java实现偶数矩阵(Even Parity, UVa 11464)

    偶数矩阵(Even Parity, UVa 11464) 问题描述 给你一个n×n的01矩阵(每个元素非0即1),你的任务是把尽量少的0变成1, 使得每个元素的上.下.左.右的元素(如果存在的话)之和 ...

  6. Java实现 洛谷 P1508 Likecloud-吃、吃、吃

    import java.util.Arrays; import java.util.Scanner; public class Main { static int n, m; static int[] ...

  7. Java实现 蓝桥杯 历届试题 矩阵翻硬币

    问题描述 小明先把硬币摆成了一个 n 行 m 列的矩阵. 随后,小明对每一个硬币分别进行一次 Q 操作. 对第x行第y列的硬币进行 Q 操作的定义:将所有第 ix 行,第 jy 列的硬币进行翻转. 其 ...

  8. Java实现 串中取3个不重复字母

    从标准输入读入一个由字母构成的串(不大于30个字符). 从该串中取出3个不重复的字符,求所有的取法. 取出的字符,要求按字母升序排列成一个串. 不同的取法输出顺序可以不考虑. 例如: 输入: abc ...

  9. java实现第七届蓝桥杯四平方和

    四平方和 四平方和 四平方和定理,又称为拉格朗日定理: 每个正整数都可以表示为至多4个正整数的平方和. 如果把0包括进去,就正好可以表示为4个数的平方和. 比如: 5 = 0^2 + 0^2 + 1^ ...

  10. PAT 反转链表

    给定一个常数 K 以及一个单链表 L,请编写程序将 L 中每 K 个结点反转.例如:给定 L 为 1→2→3→4→5→6,K 为 3,则输出应该为 3→2→1→6→5→4:如果 K 为 4,则输出应该 ...