洛谷 P2194 HXY烧情侣【Tarjan缩点】 分析+题解代码
洛谷 P2194 HXY烧情侣【Tarjan缩点】 分析+题解代码
题目描述:
众所周知,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。
题目分析:
一道典型的tarjan缩点裸题
不会tarjan的小伙伴可以参考我的另一篇博客
图论算法-Tarjan模板 【缩点;割顶;双连通分量】
tarjan缩点后每个强连通分量中最小的点权相加即为所求最小值
方案数可运用乘法原理
记录每个缩点中有几个最小的点权
在相乘时取膜即可
献上蒟蒻代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<stack>
using namespace std;
int n,m;
int w[1000010];
vector<int> map[100010];
int dfn[100010],low[100010];
int col[100010];
int tot,colnum;
stack<int> st;
bool ins[100010];
int minn[100010];//记录每个强连通分量中的最小点权
int num[100010];//记录每个强连通分量有几个最小点权
int ans;//最小花费
int sum=1;//方案数
void tarjan(int u)
{
low[u]=dfn[u]=++tot;
st.push(u);
ins[u]=true;
for(int j=0;j<map[u].size();j++)
{
int v=map[u][j];
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])
{
colnum++;
int temp;
do
{
temp=st.top();
st.pop();
ins[temp]=false;
col[temp]=colnum;
if(w[temp]<minn[colnum])
{
//更新最小值及最小值个数
minn[colnum]=w[temp];
num[colnum]=1;
}
else if(w[temp]==minn[colnum])
num[colnum]++;//更新最小点权数
}
while(temp!=u);
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>w[i];
cin>>m;
for(int i=1;i<=m;i++)
{
int s,t;
cin>>s>>t;
map[s].push_back(t);
}
memset(minn,127,sizeof(minn));
for(int i=1;i<=n;i++)
{
if(!dfn[i])
tarjan(i);
}
for(int i=1;i<=colnum;i++)
{
ans+=minn[i];
sum*=num[i]%1000000007;
}
cout<<ans<<" "<<sum;
return 0;
}
洛谷 P2194 HXY烧情侣【Tarjan缩点】 分析+题解代码的更多相关文章
- 洛谷P2194 HXY烧情侣
题目描述 众所周知,\(HXY\)已经加入了\(FFF\)团.现在她要开始喜\((sang)\)闻\((xin)\)乐\((bing)\)见\((kuang)\)地烧情侣了.这里有\(n\)座电影院, ...
- P2194 HXY烧情侣【Tarjan】
前言 当时和\(GYZ\)大佬一起做这个题,他表示这个题对他很不友好(手动滑稽) 题目描述 众所周知,\(HXY\) 已经加入了 \(FFF\) 团.现在她要开始喜(sang)闻(xin)乐(bing ...
- 洛谷 P3627 [APIO2009]抢掠计划 Tarjan缩点+Spfa求最长路
题目地址:https://www.luogu.com.cn/problem/P3627 第一次寒假训练的结测题,思路本身不难,但对于我这个码力蒟蒻来说实现难度不小-考试时肛了将近两个半小时才刚肛出来. ...
- 【洛谷P5008 逛庭院】tarjan缩点+贪心
既然没有题解,那么我就来提供给一份. -- 首先我们看到数据范围.妈耶!数据这么大,一开始还想用个DP来做,但是看着就不行,那么根据这个数据范围,我们大致可以猜到这道题的算法是一个贪心,那么我们怎么贪 ...
- 【luogu P2194 HXY烧情侣】 题解
题目链接:https://www.luogu.org/problemnew/show/P2194 第一问:缩点并且统计其强连通分量里的最小耗费.把所有强连通分量的最小耗费加起来. 第二问:统计在每个强 ...
- luogu P2194 HXY烧情侣
残忍的题面 我们来看这一道题,其实冗长的题目告诉我们一个核心——用tarjan tarjan是用来干什么呢?是用来求强连通分量(代码中指sc) 求出来又有什么用呢?每当我们求出一个强连通分量时,就去计 ...
- 洛谷 2921 记忆化搜索 tarjan 基环外向树
洛谷 2921 记忆化搜索 tarjan 传送门 (https://www.luogu.org/problem/show?pid=2921) 做这题的经历有点玄学,,起因是某个random题的同学突然 ...
- 洛谷P4014 分配问题【最小/大费用流】题解+AC代码
洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...
- 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication【最小割】分析+题解代码
洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication[最小割]分析+题解代码 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流. ...
随机推荐
- Django将request对象传入模板配置
对于很多时候,需要从模板中获取很请求中很多内容,比如当前请求的url,当前的session变量中的某个值,这时候我们可以通过配置可将request对象传递进模板. django1.10版本: sett ...
- django 编程小结
1.增删改查 add obj = Obj(atr=atr..) obj.save() update: __dict__ 遍历 del: 根据id列表删除 query: 首次查询: 直接跳转至页面,前端 ...
- 2018/1/27 每日一学 最长不降序子序列的O(n*logn)算法
手动维护一个数组模拟即可,233-- 可以使用algorithm中的lower_bound(相当于二分) 代码如下: #include<cstdio> #include<algori ...
- python_20_socket
什么是socket? -- 通过各种协议,发送和接收数据,实现网络通信 -- 在python3中,网络发送只能发二进制数据 OSI七层模型是什么? 应用 表示 会话 传输 网络 ...
- MySQL中group_concat()函数的排序方法
group_concat()函数的参数是可以直接使用order by排序的.666..下面通过例子来说明,首先看下面的t1表. 比如,我们要查看每个人的多个分数,将该人对应的多个分数显示在一起,分数要 ...
- springMVC中@RequestParam和@RequestBody注解的用法
springMVC中@RequestParam注解用在Controller层获解析.提取参数,当然你也可以用request.getParameter("name")来获取参数,而@ ...
- python --- queue模块使用
1. 什么是队列? 学过数据结构的人都知道,如果不知道队列,请Google(或百度). 2. 在python中什么是多生产者,多消费模型? 简单来说,就是一边生产(多个生产者),一边消费(多个消费者) ...
- C#基础(四)--值类型和引用类型,栈和堆的含义
本文主要是讨论栈和堆的含义,也就是讨论C#的两种类据类型:值类型和引用类型: 虽然我们在.net中的框架类库中,大多是引用类型,但是我们程序员用得最多的还是值类型. 引用类型如:string,Obje ...
- Django的ORM实现数据库事务操作
在Django中实现数据库的事务操作 在学习MySQL数据库时,MySQL数据库是支持原子操作的. 什么是数据库的原子操作呢??打个比方,一个消费者在一个商户里刷信用卡消费. 交易正常时,银行在消费者 ...
- js 面向对象 继承
继承方式有四种: 1.call 2.apply 3.prototype 4.for in call 和 apply 的主要区别: call 传参数只能一个一个的传, apply 因为是用数组,所以可以 ...