UVA12167 Proving Equivalences

题意翻译

题目描述 在数学中,我们常常需要完成若干命题的等价性证明。

例如:有4个命题a,b,c,d,要证明他们是等价的,我们需要证明a<=>b,然后b<=>c,最后c<=>d。注意每次证明是双向的,因此一共完成了6次推导。另一种证明方法是:证明a->b,然后b->c,接着c->d,最后d->a,只须4次证明。

现在你任务是证明 n 个命题全部等价,且你的朋友已经为你作出了m次推导(已知每次推导的内容),你至少还需做几次推导才能完成整个证明。

输入数据 有T(T<=100)组数据,每组数据第一行为两个整数n和m(1<=n<=20000, 1<=m<=50000),即命题数和已完成的推导个数(编号为1..n)。以下m行每行包含两个整数s1和s2(1<=s1,s2<=n,s1!=s2),表明已经证明了s1->s2。

输出数据 输出还需要做推导数的最小值。

感谢@hicc0305 提供的翻译


错误日志: 没有特判 \(numc = 1\) (即任意两点互通)时答案为 \(0\) 的情况


Solution

强联通分量搞成 \(DAG\) , 因为需要加边把图变为一个大强联通分量, 考虑出度和入度为 \(0\) 的点的数量, 这些点无法被到达或无法到达其他点, 输出计数的较大值即可满足所有点互达

Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define cln(s, v) memset(s, v, sizeof(s))
typedef long long LL;
using namespace std;
int RD(){
int out = 0,flag = 1;char c = getchar();
while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
return flag * out;
}
const int maxn = 1000019,INF = 1e9 + 19;
int head[maxn],nume = 1;
struct Node{
int v,dis,nxt;
}E[maxn << 3];
void add(int u,int v,int dis){
E[++nume].nxt = head[u];
E[nume].v = v;
E[nume].dis = dis;
head[u] = nume;
}
int DFN[maxn], LOW[maxn], INDEX;
int numc, col[maxn];
bool ins[maxn];
int S[maxn], top;
void Tarjan(int u){
DFN[u] = LOW[u] = ++INDEX;
S[++top] = u;ins[u] = 1;
for(int i = head[u];i;i = E[i].nxt){
int v = E[i].v;
if(!DFN[v])Tarjan(v), LOW[u] = min(LOW[u], LOW[v]);
else if(ins[v])LOW[u] = min(LOW[u], DFN[v]);
}
if(DFN[u] == LOW[u]){
numc++;
while(S[top + 1] != u){
col[S[top]] = numc;
ins[S[top--]] = 0;
}
}
}
int ing[maxn], outg[maxn];
void init(){
cln(head, 0), nume = 1;
INDEX = 0, cln(DFN, 0), cln(LOW, 0);
cln(col, 0), numc = 0;
cln(ing, 0), cln(outg, 0);
}
int T, num, nr;
int main(){
T = RD();
while(T--){
init();
num = RD();nr = RD();
for(int i = 1;i <= nr;i++){
int u = RD(), v = RD();
add(u, v, 0);
}
for(int i = 1;i <= num;i++)if(!DFN[i])Tarjan(i);
if(numc == 1){printf("0\n");continue;}
for(int u = 1;u <= num;u++){
for(int i = head[u];i;i = E[i].nxt){
int v = E[i].v;
if(col[u] != col[v]){
ing[col[v]]++;
outg[col[u]]++;
}
}
}
int in = 0, out = 0;
for(int i = 1;i <= numc;i++){
if(ing[i] == 0)in++;
if(outg[i] == 0)out++;
}
printf("%d\n", max(in, out));
}
return 0;
}

UVA12167 Proving Equivalences的更多相关文章

  1. hdu 2767 Proving Equivalences

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

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

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

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

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

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

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

  5. HDU 2767 Proving Equivalences(至少增加多少条边使得有向图变成强连通图)

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

  6. HDU 2767 Proving Equivalences (Tarjan)

    Proving Equivalences Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other ...

  7. HDU 2767 Proving Equivalences (强联通)

    pid=2767">http://acm.hdu.edu.cn/showproblem.php?pid=2767 Proving Equivalences Time Limit: 40 ...

  8. Proving Equivalences (hdu 2767 强联通缩点)

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

  9. HDU2767 Proving Equivalences(加边变为强联通图)

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

随机推荐

  1. Daily Scrum (2015/10/21)

    今天可以说是项目正式开始的第一天,由于大家缺乏做团队项目的经验,对TFS的使用都还不太熟悉,所以今天大家的主要工作是熟悉TFS的使用和对代码进行初步的理解.我们预计需要2-3天时间来理解透彻源代码.以 ...

  2. Bag类课后作业

    20162316 Bag课后作业 下面小标题都是码云链接 实现代码 import java.util.Arrays; public class Bag implements BagInterface ...

  3. Hibernate笔记④--一级二级缓存、N+1问题、saveorupdate、实例代码

    一级缓存及二级缓存 一级缓存也是Session 缓存     一个链接用户的多次查询使用缓存     跨用户 则无缓存     hibernate自带的 get和load都会填充并利用一级缓存 二级缓 ...

  4. beat冲刺(5/7)

    目录 摘要 团队部分 个人部分 摘要 队名:小白吃 组长博客:hjj 作业博客:beta冲刺(5/7) 团队部分 后敬甲(组长) 过去两天完成了哪些任务 ppt制作中 数据集标注 接下来的计划 制作p ...

  5. Internet History, Technology and Security (Week4)

    Week4. We are now moving into Week 4! This week, we will be covering commercialization and growth. T ...

  6. Redis&PHP的使用安装-windows版

    Redis是一个Key-value的数据结构存储系统,可以以数据库的形式,缓存系统,消息处理器使用,它支持的存储value类型很多,例如,string.list(链表).set(集合).zset(so ...

  7. go 面试题总结

    1.什么是goroutine,他与process, thread有什么区别? 2. 什么是channel,为什么它可以做到线程安全? 3. 了解读写锁吗,原理是什么样的,为什么可以做到? 4. 如何用 ...

  8. vSphere下安装Hyper-V

    在vSphere 5.5中默认是无法嵌套安装Hyper-V的,必须在vSphere中稍作修改. 1. 勾选这两个选项,如果是灰色,请升级虚拟机版本至最新: 2. 在配置文件中手动加入这一行参数: 3. ...

  9. 微信小程序 功能函数 手机号验证*

    // 登录手机验证 loginPhone: function (e) { var phone = e.detail.value; if (!(/^1[34578]\d{9}$/.test(phone) ...

  10. app流畅度测试--使用SM

    通过测量应用的帧率FPS并不能准确评价App的流畅度,FPS较低并不能代表当前App在UI上界面不流畅,而1s内VSync这个Loop运行了多少次更加能说明当前App的流畅程度. 那么我们可以直接在A ...