题目大意:有n个命题,已知其中的m个推导,要证明n个命题全部等价(等价具有传递性),最少还需要做出几次推导。

题目分析:由已知的推导可以建一张无向图,则问题变成了最少需要增加几条边能使图变成强连通图。找出所有的强连通分量,将每一个连通分量视作一个大节点,则整张图变成了一张DAG。设出度为0的大节点个数为a,入度为0的大节点个数为b,则答案就是max(a,b)。为什么是这样呢?因为要使等价证明前进下去,每个大节点的出度和入度都必须不能是0。

代码如下:

# include<iostream>
# include<cstdio>
# include<vector>
# include<stack>
# include<cstring>
# include<algorithm>
using namespace std; const int maxn=20005;
int n,m,low[maxn],pre[maxn],sccno[maxn],in[maxn],out[maxn],dfs_cnt,scc_cnt;
stack<int>S;
vector<int>G[maxn]; void dfs(int u)
{
low[u]=pre[u]=++dfs_cnt;
S.push(u);
for(int i=0;i<G[u].size();++i){
int v=G[u][i];
if(!pre[v]){
dfs(v);
low[u]=min(low[u],low[v]);
}else if(!sccno[v])
low[u]=min(pre[v],low[u]);
}
if(low[u]==pre[u]){
++scc_cnt;
while(1){
int x=S.top();
S.pop();
sccno[x]=scc_cnt;
if(x==u)
break;
}
}
} void findScc()
{
memset(low,0,sizeof(low));
memset(pre,0,sizeof(pre));
memset(sccno,0,sizeof(sccno));
dfs_cnt=scc_cnt=0;
for(int i=0;i<n;++i) if(!pre[i])
dfs(i);
} void read()
{
int a,b;
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i) G[i].clear();
while(m--)
{
scanf("%d%d",&a,&b);
--a,--b;
G[a].push_back(b);
}
} void solve()
{
for(int i=1;i<=scc_cnt;++i)
in[i]=out[i]=1;///先假设所有分量的出度和入度都是0;
for(int i=0;i<n;++i)
for(int j=0;j<G[i].size();++j)
if(sccno[i]!=sccno[G[i][j]])
out[sccno[i]]=in[sccno[G[i][j]]]=0;///如果i和G[i][j]不在一个分量内,则其对应的出度和入度不是0;
int a=0,b=0;
for(int i=1;i<=scc_cnt;++i){
if(in[i]) ++a;
if(out[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--)
{
read();
findScc();
solve();
}
return 0;
}

  

UVALive-4287 Proving Equivalences (有向图的强连通分量)的更多相关文章

  1. UVALive-4287 Proving Equivalences 有向图的强连通分量+缩点

    题意:有n个命题,已知其中的m个推导,要证明n个命题全部等价(等价具有传递性),最少还需要做出几次推导. 思路:由已知的推导可以建一张无向图,则问题变成了最少需要增加几条边能使图变成强连通图.找出所有 ...

  2. UVALive - 4287 - Proving Equivalences(强连通分量)

    Problem   UVALive - 4287 - Proving Equivalences Time Limit: 3000 mSec Problem Description Input Outp ...

  3. UVALIVE 4287 Proving Equivalences (强连通分量+缩点)

    题意:给定一个图,问至少加入多少条边能够使这个图强连通. 思路:首先求出这个图的强连通分量.然后把每个强连通分量缩成一个点.那么这个图变成了一个DAG,求出全部点的入度和出度,由于强连通图中每个节点的 ...

  4. UVALive - 4287 Proving Equivalences

    给定n个命题之间的已经证明的关系如 a b表示已经证明蕴含式a→b,要求还需要再作多少次证明使得所有的命题都是等价的.将每个命题看成一个点,已经证明的命题之间连一条边,问题转化为添加多少条单向边使得图 ...

  5. UVALive 4287 SCC-Tarjan 加边变成强连通分量

    还是强连通分量的题目,但是这个题目不同的在于,问你最少要添加多少条有向边,使得整个图变成一个强连通分量 然后结论是,找到那些入度为0的点的数目 和 出度为0的点的数目,取其最大值即可,怎么证明嘛... ...

  6. UvaLive 4287 Proving Equivalences 强连通缩点

    原题链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  7. UVALive 4287 Proving Equivalences(缩点)

    等价性问题,给出的样例为 a->b的形式,问要实现全部等价(即任意两个可以互相推出),至少要加多少个形如 a->b的条件. 容易想到用强连通缩点,把已经实现等价的子图缩掉,最后剩余DAG. ...

  8. UVA247- Calling Circles(有向图的强连通分量)

    题目链接 题意: 给定一张有向图.找出全部强连通分量,并输出. 思路:有向图的强连通分量用Tarjan算法,然后用map映射,便于输出,注意输出格式. 代码: #include <iostrea ...

  9. 『Tarjan算法 有向图的强连通分量』

    有向图的强连通分量 定义:在有向图\(G\)中,如果两个顶点\(v_i,v_j\)间\((v_i>v_j)\)有一条从\(v_i\)到\(v_j\)的有向路径,同时还有一条从\(v_j\)到\( ...

  10. 图->连通性->有向图的强连通分量

    文字描述 有向图强连通分量的定义:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly co ...

随机推荐

  1. ORACLE USERENV函数

    ORACLE USERENV函数 USERENV返回关于当前会话的信息.此信息可以用于编写一个应用程序特定的审计跟踪表或确定特定于语言的角色目前使用的会话. 参数 功能 CLINET_INFO 返回最 ...

  2. 使用jQuery为文本框、单选框、多选框、下拉框、下拉多选框设值及返回值的处理

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  3. [golang note] 错误处理

    错误处理 • 错误处理的标准模式 √ golang错误处理的标准模式:error接口. √ golang函数如果要返回错误,规范上是将error作为多返回值中的最后一个,但这并非是强制要求. ▶ er ...

  4. [React-Native]入门(Hello World)

    (1)需要一台Mac(OSX),这个是前提,建议还是入手一本啦. (2)在Mac上安装Xcode,建议Xcode 6.3以上版本 (3)安装node.js:https://nodejs.org/dow ...

  5. ionic 配置打包环境

    配置java环境就不说了,太简单 下载AndroidSdkAndroid SDK Tools翻过墙的朋友可以去Google Android的官网上下载:http://developer.android ...

  6. vue工程权限怎么配置?

    vue工程权限怎么配置? router.beforeEach((to, from, next) => { }):方法的to参数能拿到router设置的对象信息,如: { path: " ...

  7. 28UDP

    UDP通信流程步骤: 服务端: 等待(被动)接收发送 1: 创建 socket:  socket() 2: 绑定端口:      bind() 3: 读取消息:      read() 4: 发送消息 ...

  8. android整理的一些基础知识

    本篇文章内容大部分是来源于本人实际开发中的心得总结,不是非常全面,咱才疏学浅,如果有错误的地方恳请各位指出哦~ android四大组件 四大组件包括:Activity(活动),Service(服务), ...

  9. 设置小窗口Activity

    http://blog.csdn.net/xieyihua1994/article/details/52586270 我们知道Activity本身是没有界面的.所以activity类创建了一个窗口,开 ...

  10. list元素排序需要满足两个条件

    关于List 说到list,我的印象就是单值集合接口,插入取出是有序的,允许重复,用他的实现类用的最频繁的就是ArrayList了.如果我现在有一个list,插入了一些值,想让里面的值按照我自定义的规 ...