Your city has n junctions. There are m one-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 junction ican protect junction j if either i = j or the police patrol car can go to j from i and then come back to i.
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 and in 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.
In the first line, you will be given an integer n, number of junctions (1 ≤ n ≤ 105). In the next line, n space-separated integers will be given. The ith integer is the cost of building checkpost at the ith junction (costs will be non-negative and will not exceed 109).
The next line will contain an integer m (0 ≤ m ≤ 3·105). And each of the next m lines contains two integers ui and vi (1 ≤ ui, vi ≤ n; u ≠ v). A pair ui, vi means, that there is a one-way road which goes from ui to vi. There will not be more than one road between two nodes in the same direction.
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).
3 1 2 3 3 1 2 2 3 3 2
3 1
5 2 8 0 6 0 6 1 4 1 3 2 4 3 4 4 5 5 1
8 2
10 1 3 2 2 1 3 1 4 10 10 12 1 2 2 3 3 1 3 4 4 5 5 6 5 7 6 4 7 3 8 9 9 10 10 9
15 6
2 7 91 2 1 2 2 1
7 1
题意:
给出 N(1 ~ 100000) ,代表有 N 个点,后给出这 N 个点每个点的站点花费金额。后给出 M (0 ~ 300000),代表有 M 条单向边,每条单向边给出两个数 A,B,代表 A 到 B。现要建立检查站,检查站只能建立在某个站点上,问如何建立,使检查站和任意一站点能互相达到,输出最小花费金额和建立的方法数。
思路:
强连通分量。找出每个强连通分量的最小金额数 和 对应的数量。对于最小金额数求和求出最小花费金额 ,乘法定理求出方法数。注意两者都要用 ll。
AC:
#include <cstdio> #include <cstring> #include <algorithm> #include <stack> #include <vector> using namespace std; typedef struct {int m, num;} node; const int NMAX = 100005; const int EMAX = NMAX * 4; const int INF = 1000000005; int n, mon[NMAX]; vector<int> v[NMAX]; int scc_cnt, dfs_clock; int pre[NMAX], cmp[NMAX], low[NMAX]; stack<int> s; node res[NMAX]; void dfs(int u) { pre[u] = low[u] = ++dfs_clock; s.push(u); for (int i = 0; i < v[u].size(); ++i) { if (!pre[ v[u][i] ]) { dfs( v[u][i] ); low[u] = min(low[u], low[ v[u][i] ]); } else if (!cmp[ v[u][i] ]) { low[u] = min(low[u], pre[ v[u][i] ]); } } if (low[u] == pre[u]) { ++scc_cnt; for(;;) { int x = s.top(); s.pop(); cmp[x] = scc_cnt; if (x == u) break; } } } void scc() { dfs_clock = scc_cnt = 0; memset(pre, 0, sizeof(pre)); memset(cmp, 0, sizeof(cmp)); for (int i = 1; i <= n; ++i) { if (!pre[i]) dfs(i); } } int main() { scanf("%d", &n); for (int i = 1; i <= n; ++i) scanf("%d", &mon[i]); int m; scanf("%d", &m); while (m--) { int f, t; scanf("%d%d", &f, &t); v[f].push_back(t); } scc(); for (int i = 1; i <= scc_cnt; ++i) res[i].m = INF; for (int i = 1; i <= n; ++i) { if (res[ cmp[i] ].m == mon[i]) ++res[ cmp[i] ].num; if (res[ cmp[i] ].m > mon[i]) { res[ cmp[i] ].m = mon[i]; res[ cmp[i] ].num = 1; } } __int64 sum_mon = 0,sum = 1; for (int i = 1; i <= scc_cnt; ++i) { sum_mon += res[i].m; sum = sum * res[i].num % 1000000007; } printf("%I64d %I64d\n", sum_mon, sum); return 0; }
相关推荐
"有向图的强连通分量(scc)Tarjan算法" Tarjan算法是基于深度优先搜索的算法,用于求解有向图的强连通分量(scc)。强连通分量是指图中每两个顶点之间至少存在一条路径的子图。Tarjan算法的主要思想是通过深度...
)图作为输入,并以拓扑顺序返回其强连通分量作为输出 循环依赖 在各种情况下,依赖关系可能是循环的,并且必须同时执行一组相互依赖的操作。同时执行成本高昂的情况并不少见。使用 Tarjan 算法,可以确定执行相互...
POJ2186-Popular Cows ...【Tarjan+极大强连通分量+缩点】 解题报告+AC代码 http://hi.csdn.net/!s/BGDH68 附:我所有的POJ解题报告链接 . http://blog.csdn.net/lyy289065406/article/details/6642573
图论是计算机科学和数学中的一个重要分支,它研究如何用图形..."图论- 图的连通性- Tarjan 求强连通分量.pdf"文档可能包含了对这个算法的详细解释、伪代码、实例分析以及相关习题,是学习和理解Tarjan算法的宝贵资源。
tarjan算法呕心沥血之作,动画演示,步步清晰可见,详细的描述了tarjan算法的工作过程,比网上的单纯的图片更加容易理解。
使用Tarjan算法进行快速计算强连通分量,C++语言实现。
通过以上步骤,Tarjan算法可以有效地找到有向图中的所有强连通分量。这个过程通过深度优先搜索确保了对强连通分量的完整识别,同时利用堆栈保存了搜索状态,使得算法在实际应用中表现出较高的效率。 总的来说,...
Tarjan算法是由Robert Tarjan在1972年提出的,用于高效地找出有向图中的所有强连通分量。该算法的时间复杂度为 O(N + M),其中 N 是顶点数,M 是边的数量。相比于直接基于定义的方法(时间复杂度 O(N^2 + M)),...
Tarjan算法是图论领域中一个经典的算法,由美国计算机科学家罗伯特·塔扬(Robert Tarjan)提出,主要用于深度优先搜索(DFS)遍历图中的节点,并对图中的强连通分量(Strongly Connected Components,SCCs)或双...
总结来说,"图论- 图的连通性- Tarjan 缩点.rar"提供的资料详细介绍了图的连通性概念,特别是在有向图中的强连通性,以及Tarjan算法如何通过深度优先搜索来发现和处理这些连通性。这个算法在实际的图处理和问题求解...
《Tarjan算法——高效求解有向图强连通分量》 Tarjan算法是一种用于求解有向图强连通分量的高效算法,它基于深度优先搜索(DFS)策略,由著名计算机科学家Robert Tarjan提出。在有向图中,如果两个顶点之间存在双向...
在网络算法部分,Tarjan重点讲解了图的遍历(深度优先搜索和广度优先搜索)、连通性问题(并查集、强连通分量)、图的最短路径算法(Dijkstra算法、Floyd-Warshall算法)、拓扑排序、最小生成树(Kruskal算法、Prim...
实现用于查找有向图的强连通分量的 Tarjan 算法。 在强连通分量 (SCC) 中,每个节点到每个其他节点都有一条路径。 SCC 是不相交的。 入度或出度为零或属于无环图的节点自己形成 SCC。 接受邻接矩阵作为输入。 为了...
+ 有向图强连通分量 Tarjan 算法(Tarjan 算法+静态邻接表) + 有向图强连通分量 Gabow 算法 + 无向图连通分支(dfs/bfs 邻接阵) + 有向图强连通分支(dfs/bfs 邻接阵)O(n^2) + 有向图最小点基(邻接阵)O(n^2) * ...
Tarjan算法求割边 Tarjan算法是图论中的一种常见算法,用于寻找有向图中的割点和割边。割边是指删除该边后,图将被分割成两个或多个连通分量的边。 Tarjan算法可以快速地找到所有的割边。 割边的定义与割点的定义...
纯代码
Tarjan算法,源于著名计算机科学家Robert Tarjan,是一种在图论中广泛使用的高效算法,尤其在处理强连通分量的问题上展现出强大的能力。本文将深入探讨Tarjan算法的核心思想及其在2-SAT问题中的应用。 为何讲解...
Tarjan算法,全称为Robert Tarjan的强连通分量算法,是图论中的一个经典算法,主要用于找出有向图中的强连通分量。在C++编程中,它能有效地处理复杂的图结构问题,尤其是在分析网络流、最短路径等场景下。本文将深入...
总结来说,“图论- 图的连通性- Tarjan 求双连通分量.rar”这个资源涵盖了图论中的核心概念——图的连通性和双连通分量,以及Tarjan算法这一求解双连通分量的经典方法。理解并掌握这些知识对于学习高级图算法和解决...