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. 第39次Scrum会议(12/5)【欢迎来怼】

    一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,阚博文 小组照片 二.开会信息 时间:2017/12/5 11:35~11:57,总计22min.地点:东北师 ...

  2. NEWBEE软件团队 人员分配情况及分数获得方式

    人员分配: PM:李桐  王骜 dev:王骜 刘垚鹏 安康  林旭鹏  黄新越 test:黄伟龙 李桐 马佐霖 黄新越 注:黄新越为女生,不方便平时的交流,所以任务分配较为灵活,特分在两个组里. 评分 ...

  3. vim相关命令单独记载

    1. 无敌的可扩展性 1.1 可扩展性给了软件强大的生命 曾几何时,Windows用户对软件的可扩展性没有概念,他们只能对他们使用的软件进行非常有限的定制.扩展软件的权利保留在软件开发者手中.软件的使 ...

  4. 奔跑吧DKY——团队Scrum冲刺阶段-Day 2

    今日完成任务 各个成员今日完成的任务(如果完成的任务为开发或测试任务,需给出对应的Github代码签入记录截图:如果完成的任务为调研任务,需给出对应的调研总结博客链接:如果完成的任务为学习技术任务,需 ...

  5. sprint会议1

    昨天:进行第一次站立会议,讨论冲刺阶段,目标,任务认领,制作索引卡. 今天:准备查找安卓APP开发的有关资料,安装有关软件. 遇到的问题:对这方面毫无了解,不知道怎么开始,从哪开始,完全没经验.

  6. WebGL学习笔记(二)

    目录 绘制多个顶点 使用缓冲区对象 类型化数组 使用drawArrays()函数绘制图形 图形的移动 图形的旋转 图形的缩放 绘制多个顶点 使用缓冲区对象 创建缓冲区对象 var vertexBuff ...

  7. 404 Note Found 团队会议纪要

    目录 团队会议 会议纪要1 会议纪要2 会议纪要3 会议纪要4 会议纪要5 会议纪要6 团队会议 会议纪要1 会议纪要2 会议纪要3 会议纪要4 会议纪要5 会议纪要6

  8. MapReduce编程之Semi Join多种应用场景与使用

    Map Join 实现方式一 ● 使用场景:一个大表(整张表内存放不下,但表中的key内存放得下),一个超大表 ● 实现方式:分布式缓存 ● 用法: SemiJoin就是所谓的半连接,其实仔细一看就是 ...

  9. PAT 1042 字符统计

    https://pintia.cn/problem-sets/994805260223102976/problems/994805280817135616 请编写程序,找出一段给定文字中出现最频繁的那 ...

  10. Delphi中使用OLE方法操作Excel

    首先创建 Excel 对象,使用ComObj: var ExcelApp: Variant; ExcelApp := CreateOleObject( ′Excel.Application′ ); 注 ...