【洛谷P2194】 HXY烧情侣 强连通分量+tarjan+统计个数
2016-12-12 19:23
211 查看
题目描述
众所周知,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求强连通分量,求强连通分量的时候同时维护一个数组表示该强连通分量中花费最少的点的花费是多少。最后统计每个强连通分量等于该强连通分量最小花费的点有多少个,更新答案。
众所周知,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求强连通分量,求强连通分量的时候同时维护一个数组表示该强连通分量中花费最少的点的花费是多少。最后统计每个强连通分量等于该强连通分量最小花费的点有多少个,更新答案。
#include<iostream> #include<cstdio> #include<cstring> #define N 300006 #define MOD 1000000007 using namespace std; struct node { int from,to,next; }e ; int low ,dfn ,insex,stack ,tot; bool instack ; int t,ans ; int e_num,head ; bool flag ; int r,n,p,num ,color ,ru ,m; int a ,b ,s ; void add(int from,int to) { ++e_num; e[e_num].from=from; e[e_num].to=to; e[e_num].next=head[from]; head[from]=e_num; } void tarjan(int u) { int i; low[u]=dfn[u]=++insex; instack[u]=true; stack[++tot]=u; for (i=head[u];i;i=e[i].next) { int v=e[i].to; if (!dfn[v]) { tarjan(v); low[u]=min(low[v],low[u]); } else if (instack[v]) { low[u]=min(low[u],dfn[v]); } } if (low[u]==dfn[u]) { int tmp=0; ++t; while (tmp!=u) { tmp=stack[tot--]; instack[tmp]=false; ans[t]=min(ans[t],s[tmp]); color[tmp]=t; } } } void slove() { int i; memset(dfn,0,sizeof(dfn)); for (i=1;i<=n;i++) if (!dfn[i]) tarjan(i); } int main() { int x,y,i,sum=0; scanf("%d",&n); memset(s,127/3,sizeof(s)); for (i=1;i<=n;i++) { scanf("%d",&x); s[i]=x; } scanf("%d",&m); for (i=1;i<=m;i++) { scanf("%d%d",&x,&y); add(x,y); a[i]=x;b[i]=y; //x指向y } memset(ans,127/3,sizeof(ans)); int maxx=ans[0]; slove(); int tt=t; for (i=1;i<=n;i++) { if (s[i]==ans[color[i]]) num[color[i]]++; } long long sum1=1; for (i=1;i<=t;i++) { sum+=ans[i]; sum1*=num[i]; sum1=sum1%MOD; } printf("%d %lld",sum,sum1); }
相关文章推荐
- 洛谷 P2194 HXY烧情侣【Tarjan缩点】 分析+题解代码
- 洛谷【P2194】HXY烧情侣
- 洛谷P2194 HXY烧情侣
- tarjan强连通分量 洛谷P1262 间谍网络
- [LUOGU] P2194 HXY烧情侣
- HXY烧情侣(洛谷 2194)
- 洛谷2661-tarjan-强连通分量
- 洛谷P1726 上白泽慧音(Tarjan强连通分量)
- 洛谷-统计单词数-简单字符串
- P2048 洛谷 统计和
- 洛谷-统计数字-NOIP2007提高组复赛
- tarjan 算法(求强连通分量)
- Tarjan强联通分量-洛谷P2746 [USACO5.3]校园网Network of Schools
- ZOJ 3795 Grouping 强连通分量-tarjan
- [POJ1236]Network of Schools(Tarjan缩点+强连通分量)
- 图论算法(6)(更新版) --- Tarjan算法求强连通分量
- 【题解】 [HAOI2006]受欢迎的牛(强连通分量 tarjan)
- 洛谷 2921 记忆化搜索 tarjan 基环外向树
- 洛谷 1262 间谍网络 Tarjan 图论
- 树链剖分:洛谷 P2590 [ZJOI2008]树的统计