hdu2767 Proving Equivalences Tarjan缩点
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4343 Accepted Submission(s): 1541
Let A be an n × n matrix. Prove that the following statements are equivalent:
1. A is invertible.
2. Ax = b has exactly one solution for every n × 1 matrix b.
3. Ax = b is consistent for every n × 1 matrix b.
4. 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?
* 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.
* One line with the minimum number of additional implications that need to be proved in order to prove that all statements are equivalent.
#include <bits/stdc++.h>
using namespace std;
const int N = 20005;
const int M = 50005; struct edge {
int v, next;
edge() {}
edge(int v, int next): v(v), next(next) {}
}e[M], e2[M]; int head[N], head2[N], num[N], in[N], out[N], tot, tot2;
int low[N], dfn[N], Stack[N], belong[N];
int scc, Index, top;
bool Instack[N]; void addedge(int u, int v, bool is) {
if(is) {
e[tot] = edge(v, head[u]);
head[u] = tot++;
}else {
e2[tot2] = edge(v, head2[u]);
head2[u] = tot2++;
}
} void Tarjan(int u) {
int v;
low[u] = dfn[u] = ++Index;
Stack[top++] = u;
Instack[u] = true;
for(int i = head[u]; ~i; i = e[i].next) {
v = e[i].v;
if(!dfn[v]) {
Tarjan(v);
if(low[u] > low[v]) low[u] = low[v];
}else if(Instack[v] && low[u] > dfn[v]) {
low[u] = dfn[v];
}
} if(low[u] == dfn[u])
{
scc++;
do {
v = Stack[--top];
Instack[v] = false;
belong[v] = scc;
num[scc]++;
} while(v != u);
}
} void solve(int n)
{
memset(dfn, 0, sizeof dfn);
memset(Instack, false, sizeof Instack);
memset(num, 0, sizeof num);
Index = scc = top = 0;
for(int i = 1; i <= n; ++i) if(!dfn[i]) Tarjan(i);
}
void init() {
tot = tot2 = 0;
memset(head, -1, sizeof head);
memset(head2, -1, sizeof head2);
} int main()
{
int _; scanf("%d", &_);
while(_ --)
{
init();
int n, m, u, v;
scanf("%d%d", &n, &m);
for(int i = 1; i <= m ;++i) {
scanf("%d%d", &u, &v);
addedge(u, v, true);
}
solve(n);
memset(in, 0, sizeof in);
memset(out, 0, sizeof out); for(int u = 1; u <= n; ++u) {
for(int i = head[u]; ~i; i = e[i].next) {
int v = e[i].v;
if(belong[u] != belong[v]) {
addedge(belong[u], belong[v], false);
}
}
}
for(int u = 1; u <= scc; ++u) {
for(int i = head2[u]; ~i; i = e2[i].next) {
int v = e2[i].v;
in[v]++;
out[u]++;
}
}
int a = 0, b = 0;
for(int i = 1; i <= scc; ++i) {
if(in[i] == 0) a++;
if(out[i] == 0) b++;
}
printf("%d\n", scc == 1 ? 0 : max(a, b));
}
return 0;
}
hdu2767 Proving Equivalences Tarjan缩点的更多相关文章
- HDU2767 Proving Equivalences(加边变为强联通图)
Proving Equivalences Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- HDU2767 Proving Equivalences
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...
- UVALive 4287 Proving Equivalences(缩点)
等价性问题,给出的样例为 a->b的形式,问要实现全部等价(即任意两个可以互相推出),至少要加多少个形如 a->b的条件. 容易想到用强连通缩点,把已经实现等价的子图缩掉,最后剩余DAG. ...
- hdu2767 Proving Equivalences --- 强连通
给一个图,问至少加入�多少条有向边能够使图变成强连通的. 原图是有环的,缩点建图,在该DAG图上我们能够发现,要使该图变成强连通图必须连成环 而加入�最少的边连成环,就是把图上入度为0和出度为0的点连 ...
- hdu 2767 Proving Equivalences 强连通缩点
给出n个命题,m个推导,问最少添加多少条推导,能够使全部命题都能等价(两两都能互推) 既给出有向图,最少加多少边,使得原图变成强连通. 首先强连通缩点,对于新图,每一个点都至少要有一条出去的边和一条进 ...
- UvaLive 4287 Proving Equivalences 强连通缩点
原题链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- HDU2767Proving Equivalences tarjan缩点,如何求入度和出度最大值
给定一个有向图,问最少增加多少条边后变成强连通图 tarjan求求强连通分量并缩点,如果强连通分量个数为1,则需要边数为0, 否则为缩点后点入度和出度的最大值, 证明:当入度或者出度不为0时 ...
- hdu2767 Proving Equivalences,有向图强联通,Kosaraju算法
点击打开链接 有向图强联通,Kosaraju算法 缩点后分别入度和出度为0的点的个数 answer = max(a, b); scc_cnt = 1; answer = 0 #include<c ...
- HDU 2767 Proving Equivalences (Tarjan)
Proving Equivalences Time Limit : 4000/2000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other ...
随机推荐
- curl命令 抓取网络数据相应头
curl --verbose --data "Password=123&Username=158101068&url=http://m.vancl.com/" & ...
- MFC CheckBox
if ( BST_CHECKED == IsDlgButtonChecked( IDC_CHECK1 ) ){// 勾选}else{}
- HTML标记之Form表单
一.表单的作用 从访问的Web站点的用户那里获得信息.访问者可以使用诸如文本域.列表框.复选框以及单选按钮之类的表单元素输入信息,然后单击某个按钮提交这些信息.是客户端与服务器端的交流途径. 二.说明 ...
- linux安装软件
安装方式一: RPM包安装 安装方式二:yum包安装 安装方式三:源码包安装 安装方式四:脚步安装包 视频教程
- MFC添加菜单事件
双击draw.rc,就能看到.
- jvm分析(MD语法)
#是什么**jps** 查看所有的jvm进程,包括进程ID,进程启动的路径等等. **jstack** 观察jvm中当前所有线程的运行情况和线程当前状态.系统崩溃了?如果java程序崩溃生成cor ...
- android bitmap的放大缩小
private static Bitmap big(Bitmap bitmap) { Matrix matrix = new Matrix(); matrix.postScale(1.5f,1.5f) ...
- NYOJ题目62笨小熊
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAr4AAAK1CAIAAAChInrhAAAgAElEQVR4nO3dO3LjutaG4X8Szj0Qxx
- 玩玩Excel下的Power View
作为微软平台下的数据展示工具,Power View是一个不错的选择.而在Excel 2013下,即使你没有SharePoint的实例那么你也可以玩转它.此篇讲对Excel 2013下的Power Vi ...
- 攻城狮在路上(肆)How tomcat works(三) 连接器:Connector
在介绍中提到,Catalina中有两个主要的模块:连接器和容器.本章中你将会写一个可以创建更好的请求和响应对象的连接器,用来改进第2章中的程序.一个符合Servlet 2.3和2.4规范的连接器必须 ...