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

先求出所有的强连通分量,然后缩点构成一个SCC图,统计其中入度为0的点个数a,以及出度为0的点的个数b,max(a,b)就是需要再作的证明.注意当图一开始就是强连通时,不需要作出证明了.

来自刘汝佳算法训练指南代码:

#include <iostream>
#include <sstream>
#include <cstdio>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <string>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#define esp 1e-6
#define pi acos(-1.0)
#define pb push_back
#define mp(a, b) make_pair((a), (b))
#define in freopen("in.txt", "r", stdin);
#define out freopen("out.txt", "w", stdout);
#define print(a) printf("%d\n",(a));
#define bug puts("********))))))");
#define stop system("pause");
#define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
#define pragma comment(linker, "/STACK:102400000, 102400000")
#define inf 0x0f0f0f0f using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> pii;
typedef vector<pii,int> VII;
typedef vector<int>:: iterator IT;
const int maxn = 22222;
int pre[maxn], lowlink[maxn], sccno[maxn], dfs_clock, scc_cnt;
int in0[maxn], out0[maxn];
VI g[maxn];
stack<int> S;
void dfs(int u)
{
S.push(u);
lowlink[u] = pre[u] = ++dfs_clock;
for(int i = 0; i < g[u].size(); i++)
{
int v = g[u][i];
if(!pre[v])
{
dfs(v);
lowlink[u] = min(lowlink[u], lowlink[v]);
}
else if(!sccno[v])
{
lowlink[u] = min(lowlink[u], pre[v]);
}
}
if(lowlink[u] == pre[u])
{
scc_cnt++;
for(;;)
{
int x = S.top();
S.pop();
sccno[x] = scc_cnt;
if(x == u) break;
}
}
}
void find_scc(int n)
{
memset(pre, 0, sizeof(pre));
memset(sccno, 0, sizeof(sccno));
dfs_clock = scc_cnt = 0;
for(int i = 0; i < n; i++)
if(!pre[i]) dfs(i);
}
int main(void)
{in
int n, m;
int T;
for(int t = scanf("%d", &T); t <= T; t++)
{
for(int i = 0; i < maxn; i++)
g[i].clear();
memset(in0, 1, sizeof(in0));
memset(out0, 1, sizeof(out0));
scanf("%d%d", &n, &m);
while(m--)
{
int u, v;
scanf("%d%d", &u, &v);
u--, v--;
g[u].pb(v);
}
find_scc(n);
for(int u = 0; u < n; u++)
for(int i = 0; i < g[u].size(); i++)
{
int v = g[u][i];
if(sccno[v] != sccno[u])
in0[sccno[v]] = out0[sccno[u]] = 0;
}
int a = 0, b= 0;
for(int i = 1; i <= scc_cnt; i++)
{
if(in0[i]) a++;
if(out0[i]) b++;
}
int ans = 0;
if(scc_cnt != 1) ans = max(a, b);
printf("%d\n",ans);
}
return 0;
}

UVALive - 4287 Proving Equivalences的更多相关文章

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

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

  2. UVALive 4287 Proving Equivalences(缩点)

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

  3. UvaLive 4287 Proving Equivalences 强连通缩点

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

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

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

  5. UVALive 4287 Proving Equivalence (强连通分量)

    把证明的关系看出一张图,最终就是要所有的点都在至少一个环中.环的判断和度数有关. 用tarjan找强连通分量,在一个强连通分量点已经等价缩点以后形成一个DAG,计算入度为0的点数a, 出度为0的b,取 ...

  6. 训练指南 UVALive - 4287 (强连通分量+缩点)

    layout: post title: 训练指南 UVALive - 4287 (强连通分量+缩点) author: "luowentaoaa" catalog: true mat ...

  7. hdu 2767 Proving Equivalences

    Proving Equivalences 题意:输入一个有向图(强连通图就是定义在有向图上的),有n(1 ≤ n ≤ 20000)个节点和m(0 ≤ m ≤ 50000)条有向边:问添加几条边可使图变 ...

  8. hdoj 2767 Proving Equivalences【求scc&&缩点】【求最少添加多少条边使这个图成为一个scc】

    Proving Equivalences Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  9. Proving Equivalences(加多少边使其强联通)

    Proving Equivalences Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

随机推荐

  1. git命令(流程)

    1,配置你的信息: git config --global user.name 你的名字 git config --global user.email 你的邮箱 --global 表示所有git仓库都 ...

  2. rest的config

    <个人积累,转载请注明出处> 新手写rest wcf经常会报配置文件异常.我为了避免这种问题,将自己配好的config放这里,用的时候将ABC改成自己的,粘贴就行了. ABC是什么我就不赘 ...

  3. 两天来学习C的感受

    大学的时候曾经学习过C语言,教科书是谭浩强的绿色的书.当时根本没有好好学习,期末考试是靠老师画重点才过的. 那个时候稀里哗啦的完全听不明白,最揪心的是指针和文件操作(当时根本不知道这个世界上还有DB存 ...

  4. oracle学习(1)

    1.安装完oracle数据库后,远程第一次无法登陆,需要进入sys用户后,更改以此后才有效. 2.TNS去读取配置的时候,如果在环境变量中已经配置了 TNS_ADMIN 后,则直接从此目录下读取. 3 ...

  5. Ext.Net学习笔记15:Ext.Net GridPanel 汇总(Summary)用法

    Ext.Net学习笔记15:Ext.Net GridPanel 汇总(Summary)用法 Summary的用法和Group一样简单,分为两步: 启用Summary功能 在Feature标签内,添加如 ...

  6. 牵扯较多属性和方法的类题目,很简单的题目本来不想发的,如果有同学学到这个题目感觉太长不愿敲代码,copy走我的即可~不过还是建议自己打一打

    /* 3.设计一个"学生"类 1> 属性 * 姓名 * 生日 * 年龄 * 身高(单位是m) * 体重(单位是kg) * 性别 * C语言成绩 * OC成绩 * iOS成绩 ...

  7. Json字符与Json对象的相互转换

    Json字符与Json对象的相互转换方式有很多,接下来将为大家一一介绍下,感兴趣的朋友可以参考下哈,希望可以帮助到你 1>jQuery插件支持的转换方式: 复制代码 代码如下: $.parseJ ...

  8. attempt to write a readonly database 的解决办法

    这个问题导致我的unity项目崩溃,以至于无法打开. 第一次出现这个问题是因为在Lighting窗口中build按钮下点击了clear all baked datas,导致unity强制退出,并给出上 ...

  9. 安装kali之后

    更新源(以下设置均基于这些源) #vi /etc/apt/sources.list 把这些源加进去 ############################ debian wheezy ####### ...

  10. 九度OJ 1505 两个链表的第一个公共结点 【数据结构】

    题目地址:http://ac.jobdu.com/problem.php?pid=1505 题目描述: 输入两个链表,找出它们的第一个公共结点. 输入: 输入可能包含多个测试样例. 对于每个测试案例, ...