uva 12167 Proving Equivalences(强连通分量 + 缩点)
2015-09-15 21:10
453 查看
uva 12167 Proving Equivalences
DescriptionConsider the following exercise, found in a generic linear algebra textbook.
Let A be an n × n matrix. Prove that the following statements are equivalent:
A is invertible.
Ax = b has exactly one solution for every n × 1 matrix b.
Ax = b is consistent for every n × 1 matrix b.
Ax = 0 has only the trivial solution x = 0.
The typical way to solve such an exercise is to show a series of implications. For instance, one can proceed by showing that (a) implies (b), that (b) implies (c), that (c) implies (d), and finally that (d) implies (a). These four implications show that the four statements are equivalent.
Another way would be to show that (a) is equivalent to (b) (by proving that (a) implies (b) and that (b) implies (a)), that (b) is equivalent to (c), and that (c) is equivalent to (d). However, this way requires proving six implications, which is clearly a lot more work than just proving four implications!
I have been given some similar tasks, and have already started proving some implications. Now I wonder, how many more implications do I have to prove? Can you help me determine this?
Input
On the first line one positive number: the number of testcases, at most 100. After that per testcase:
One line containing two integers n (1 ≤ n ≤ 20000) and m (0 ≤ m ≤ 50000): the number of statements and the number of implications that have already been proved.
m lines with two integers s1 and s2 (1 ≤ s1, s2 ≤ n and s1 ≠ s2) each, indicating that it has been proved that statement s1 implies statement s2.
Output
Per testcase:
One line with the minimum number of additional implications that need to be proved in order to prove that all statements are equivalent.
Sample Input
2
4 0
3 2
1 2
1 3
Sample Output
4
2
题目大意:有四个命题a,b,c,d,我们证明我们证明他们的等价性需要进行:a←→b,然后b←→c,最后c←→d,一共需要6次推导。但四个命题的最小推导次数是:a→b, b→c,c→d,d→a只需四次推导。所以现在给出命题数量,以及已经完成的推导,问最少还需要几次推导可以完成这些命题的等价性证明。
解题思路:把命题看做结点,推导看做边,先求出原图的强连通分量。然后把每个强连通分量缩成点,就可以得到一个有向无环图(DAG)。然后判断缩点后图中入度为0的点和出度为0的点的个数,取其中大的那一个就是答案。注意,当强连通分量个数为1时,输出0。
[code]#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <cstdlib> #include <queue> #include <stack> using namespace std; typedef long long ll; const int N = 20005; int n, m; vector<int> G ; int pre , lowlink , sccno , dfs_clock, scc_cnt; int in0 , out0 ; stack<int> S; void dfs(int u) { pre[u] = lowlink[u] = ++dfs_clock; //pre[u]数组记录u点的访问时间 S.push(u); for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (!pre[v]) { dfs(v); //lowlink[u]数组记录u点所可以到达的点中最早访问到的点的访问时间 lowlink[u] = min(lowlink[u], lowlink[v]); } else if (!sccno[v]) { //v点还不属于其他强连通分量 lowlink[u] = min(lowlink[u], pre[v]); } } if (lowlink[u] == pre[u]) { //u为该强连通分量的根 //在整个强连通分量被找到时,统计强连通分量个数,以及给该强连通分量中的结点出栈并打上标记 scc_cnt++; for (;;) { int x = S.top(); S.pop(); //sccno[x]记录x点所在强连通分量的编号 sccno[x] = scc_cnt; if (x == u) break; } } } void find_scc(int n) { dfs_clock = scc_cnt = 0; //初始化 memset(sccno, 0, sizeof(sccno)); memset(pre, 0, sizeof(pre)); for (int i = 0; i < n; i++) { //最外层循环,保证每个节点都被访问 if (!pre[i]) dfs(i); } } void input() { scanf("%d %d", &n, &m); for (int i = 0; i <= n ;i++) { G[i].clear(); } for (int i = 0; i < m; i++) { int u, v; scanf("%d %d", &u, &v); u--, v--; G[u].push_back(v); } } void solve() { find_scc(n); //查找强连通分量 for (int i = 1; i <= scc_cnt; i++) in0[i] = out0[i] = 1; for (int u = 0; u < n; u++) { for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; //统计入度或出度为零的强连通分量 if (sccno[u] != sccno[v]) in0[sccno[v]] = out0[sccno[u]] = 0; //如果点u和点v在不同的强连通分量,但u到v有一条边,也就是说u所在的强连通分量到v所在的强连通分量有一条边,所以这两个强连通分量的入度或出度不为零 } } int a = 0, b = 0; for (int i = 1; i <= scc_cnt; i++) { if (in0[i]) a++; if (out0[i]) b++; } int ans = max(a, b); if (scc_cnt == 1) ans = 0; printf("%d\n", ans); } int main() { int T; scanf("%d", &T); while (T--) { input(); solve(); } return 0; }
相关文章推荐
- iOS中的UITabBarController(标签视图控制器)
- UI03_UITextField
- iOS:删除storyBoard,纯代码实现UITabBarController的视图切换功能
- ArrayBlockingQueue学习笔记
- NSDate将日期类字符串Tue Sep 15 19:00:03 +0800 2015转化为09-15 19:52日期类型的格式
- 【Java GUI】Java面板基础:JPanel
- UIBUTTON.NORMALSPRITE
- Qt 学习之路 :Qt Quick Controls
- DFGUI-- 标签交换 Tabstrip
- UIImagePickerController的静态方法
- HDOJ 1005 Number Sequence
- HDOJ 1005 Number Sequence
- UIPageControl
- UI_UITableView _新知识_02
- HDU 1423 Greatest Common Increasing Subsequence
- UIScrollView
- android之视频的播放(VedioView,SuefaceView)和图片的获得
- 10810 - Ultra-QuickSort(求逆序数)
- UISlider
- .net micro framework Netduino无法休眠