UVALive - 4287 Proving Equivalences
给定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的更多相关文章
- UVALive - 4287 - Proving Equivalences(强连通分量)
Problem UVALive - 4287 - Proving Equivalences Time Limit: 3000 mSec Problem Description Input Outp ...
- UVALive 4287 Proving Equivalences(缩点)
等价性问题,给出的样例为 a->b的形式,问要实现全部等价(即任意两个可以互相推出),至少要加多少个形如 a->b的条件. 容易想到用强连通缩点,把已经实现等价的子图缩掉,最后剩余DAG. ...
- UvaLive 4287 Proving Equivalences 强连通缩点
原题链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- UVALIVE 4287 Proving Equivalences (强连通分量+缩点)
题意:给定一个图,问至少加入多少条边能够使这个图强连通. 思路:首先求出这个图的强连通分量.然后把每个强连通分量缩成一个点.那么这个图变成了一个DAG,求出全部点的入度和出度,由于强连通图中每个节点的 ...
- UVALive 4287 Proving Equivalence (强连通分量)
把证明的关系看出一张图,最终就是要所有的点都在至少一个环中.环的判断和度数有关. 用tarjan找强连通分量,在一个强连通分量点已经等价缩点以后形成一个DAG,计算入度为0的点数a, 出度为0的b,取 ...
- 训练指南 UVALive - 4287 (强连通分量+缩点)
layout: post title: 训练指南 UVALive - 4287 (强连通分量+缩点) author: "luowentaoaa" catalog: true mat ...
- hdu 2767 Proving Equivalences
Proving Equivalences 题意:输入一个有向图(强连通图就是定义在有向图上的),有n(1 ≤ n ≤ 20000)个节点和m(0 ≤ m ≤ 50000)条有向边:问添加几条边可使图变 ...
- hdoj 2767 Proving Equivalences【求scc&&缩点】【求最少添加多少条边使这个图成为一个scc】
Proving Equivalences Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- Proving Equivalences(加多少边使其强联通)
Proving Equivalences Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
随机推荐
- php入门实现留言板
首先由一个文本文档read.txt liulan.html <!doctype html> <html lang="en"> <head> &l ...
- 《Pro Git》学习笔记
1.Git远程模型示意图 Remote:远程仓库 Repository:本地仓库 Index:暂存区 workspace:当前工作区 2.取得Git仓库 2.1 初始化新仓库 git init ...
- Vimtutor练习心得
A. 光标定位(482) ctr + g 显示光标当前所在的行数 shift + g(G) 光标移动到文档末尾 gg 移动到文档首行 数字 + G ...
- apache ambari web页面无法访问解决办法
ambari-server启动成功,但是页面无法访问 作者:Bo liang链接:http://www.zhihu.com/question/34405898/answer/115001510来源:知 ...
- dorado抽取js
dorado创建的视图文件如果有控件拥有事件的话,那么它是可以抽取js的, 右键视图->抽取JavaScript 然后就会出现一个同名的.js文件 (注意,所有的属性需要有id,因为js需要绑定 ...
- [leetcode]最长递增序列
class Solution { public: int lengthOfLIS(vector<int>& nums) { int n=nums.size(); ) ; vecto ...
- Poj 2159 / OpenJudge 2159 Ancient Cipher
1.链接地址: http://poj.org/problem?id=2159 http://bailian.openjudge.cn/practice/2159 2.题目: Ancient Ciphe ...
- crontab环境变量问题
今天设置linux定时任务时,python内调用的shell指令总执行失败,单独调用python脚本则无问题,考虑到是环境变量未生效引起. 故在执行crontab -e编辑配置文件时,将shell内执 ...
- centos 6.4 samba 权限 selinux权限配置
http://www.cnblogs.com/xiaoluo501395377/archive/2013/05/26/3100444.html(参考) SELINUX 策略 配置好samba后, 输入 ...
- leetcode problem 33 -- Search in Rotated Sorted Array
Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...