模型概述

有一DAG,问最少加多少条边能够使图强连通。

题目描述

一些学校连入一个电脑网络。那些学校已订立了协议:每个学校都会给其它的一些学校分发软件(称作“接受学校”)。注意即使 B 在 A 学校的分发列表中, A 也不一定在 B 学校的列表中。

你要写一个程序计算,根据协议,为了让网络中所有的学校都用上新软件,必须接受新软件副本的最少学校数目(子任务 A)。更进一步,我们想要确定通过给任意一个学校发送新软件,这个软件就会分发到网络中的所有学校。为了完成这个任务,我们可能必须扩展接收学校列表,使其加入新成员。计算最少需要增加几个扩展,使得不论我们给哪个学校发送新软件,它都会到达其余所有的学校(子任务 B)。一个扩展就是在一个学校的接收学校列表中引入一个新成员。

输入输出格式

输入格式:

输入文件的第一行包括一个整数 N:网络中的学校数目(2 <= N <= 100)。学校用前 N 个正整数标识。

接下来 N 行中每行都表示一个接收学校列表(分发列表)。第 i+1 行包括学校 i 的接收学校的标识符。每个列表用 0 结束。空列表只用一个 0 表示。

输出格式:

你的程序应该在输出文件中输出两行。

第一行应该包括一个正整数:子任务 A 的解。

第二行应该包括子任务 B 的解。


题目分析

第一问非常简单,就是缩点之后求入度为零的点个数。

至于第二问……一开始我想了很久,后来发现好像想复杂去了。

先加边再删边

我一开始想到的是类似于floyd的想法,来试图删去“多余的边”。

这里对于多余的边的定义是:删去这些边后不会改变图中两两点对的连通性。

那么对于点$x$,将它与所有不能到达的点$y$连边,最后再考虑哪些边是可删去的多余边。

但是这样很冗余,同时计算出的答案是会偏大的……而且我后来发现好像floyd做不到这个操作?

从图的性质考虑

先不来考虑森林(其实森林的情况也一样)比如说这样一张图:

标红的是入度为零的点;标蓝的是出度为零的点。

按照之前的想法,那就是把点1,2,3,4与其他所有它们不能到达的点相连。

但是可以发现对于点5,6来说,是能够到达所有点的;对于点2来说,它只能够到达自身;并且,所有点都能够到达点2。

那么只需要给点2向点5,6连边,就能够使图成为强连通。

更为普遍的情况则是,红点有$x$个;蓝点有$y$个,则最少加边数为$max\{x,y\}$。

 #include<bits/stdc++.h>
const int maxn = ;
const int maxm = ; int tim,dfn[maxn],low[maxn],degOut[maxn],degInn[maxn];
int stk[maxn],cnt;
int col[maxn],cols;
int edgeTot,edges[maxm],nxt[maxm],head[maxn];
int n,ans; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
void addedge(int u, int v)
{
edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
}
void tarjan(int x)
{
dfn[x] = low[x] = ++tim;
stk[++cnt] = x;
for (int i=head[x]; i!=-; i=nxt[i])
{
int v = edges[i];
if (!dfn[v])
tarjan(v),
low[x] = std::min(low[x], low[v]);
else if (!col[v])
low[x] = std::min(low[x], dfn[v]);
}
if (low[x]==dfn[x]){
col[x] = ++cols;
for (; stk[cnt]!=x; cnt--)
col[stk[cnt]] = cols;
cnt--;
}
}
int main()
{
memset(head, -, sizeof head);
n = read();
for (int i=; i<=n; i++)
{
int x;
while (x = read())
addedge(i, x);
}
for (int i=; i<=n; i++)
if (!dfn[i]) tarjan(i);
for (int i=; i<=n; i++)
for (int j=head[i]; j!=-; j=nxt[j])
if (col[i]!=col[edges[j]])
degInn[col[i]]++, degOut[col[edges[j]]]++;
for (int i=; i<=cols; i++)
if (!degOut[i]) ans++;
printf("%d\n",ans);
if (cols==) printf("0\n");
else{
int cnta = , cntb = ;
for (int i=; i<=cols; i++)
{
if (degInn[i]==) cnta++;
if (degOut[i]==) cntb++;
}
printf("%d\n",std::max(cnta, cntb));
}
return ;
}

END

概述「DAG加边至强连通」模型&&luoguP2746校园网Network of Schools的更多相关文章

  1. 概述「并查集补集转化」模型&&luoguP1330 封锁阳光大学

    奇妙的模型转化以及并查集思想 模型概述 有图$G=(V,E)$,初始所有点为白色,现在要将其中一些点染为黑色,要求染色后满足:$∀(u,v)∈E$,$∃col_u!=col_v$.求最小染色点数. 题 ...

  2. 洛谷 P2746 [USACO5.3]校园网Network of Schools (Tarjan,SCC缩点,DAG性质)

    P2746 [USACO5.3]校园网Network of Schools https://www.luogu.org/problem/P2746 题目描述 一些学校连入一个电脑网络.那些学校已订立了 ...

  3. 洛谷 P2746 [USACO5.3]校园网Network of Schools schlnet Tarjan强连通分量

    schlnet ★★★   输入文件:schlnet.in   输出文件:schlnet.out   简单对比时间限制:1 s   内存限制:128 MB 描述 一些学校连入一个电脑网络.那些学校已订 ...

  4. 【翻译】西川善司「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,前篇(2)

    Lighting和Shading(2)镜面反射的控制和模拟次级表面散射技术 http://www.4gamer.net/games/216/G021678/20140703095/index_2.ht ...

  5. 「About Blockchain(一)」达沃斯年会上的区块链

    「About Blockchain(一)」 --达沃斯年会上的区块链 写在前面:1月23日到26日,在瑞士达沃斯召开了第48届世界经济论坛.这个新闻本没有引起我格外的关注,直到前两天张老师分享给我一篇 ...

  6. 「雅礼集训 2017 Day1」 解题报告

    「雅礼集训 2017 Day1」市场 挺神仙的一题.涉及区间加.区间除.区间最小值和区间和.虽然标算就是暴力,但是复杂度是有保证的. 我们知道如果线段树上的一个结点,\(max=min\) 或者 \( ...

  7. LOJ#10064. 「一本通 3.1 例 1」黑暗城堡

    LOJ#10064. 「一本通 3.1 例 1」黑暗城堡 题目描述 你知道黑暗城堡有$N$个房间,$M$条可以制造的双向通道,以及每条通道的长度. 城堡是树形的并且满足下面的条件: 设$D_i$为如果 ...

  8. 「LOJ#10056」「一本通 2.3 练习 5」The XOR-longest Path (Trie

    #10056. 「一本通 2.3 练习 5」The XOR-longest Path 题目描述 原题来自:POJ 3764 给定一棵 nnn 个点的带权树,求树上最长的异或和路径. 输入格式 第一行一 ...

  9. 「Unity卡牌自走棋」项目NABCD分析

    项目 内容 这个作业属于哪个课程 2021学年春季软件工程(罗杰 任健) 这个作业的要求在哪里 团队项目-初次邂逅,需求分析 在这个课程的目标是 锻炼在大规模开发中的团队协作能力 这个作业在哪个具体方 ...

随机推荐

  1. [转]jQueryUI中Datepicker(日历)插件的介绍和使用

    http://jqueryui.com/datepicker/ 本文转自:http://blog.csdn.net/redarmy_chen/article/details/7400571 jQuer ...

  2. jdk 动态代理 数据连接池

    package com.itheima.datasource; import java.io.PrintWriter; import java.lang.reflect.InvocationHandl ...

  3. Qt 学习

    Qt 学习 C++ 模版 QObject 提供一个十分有用的 api,T findChild(QString, Qt::FindChildOptions),这个函数接收一个模版参数,返回模版参数的类型 ...

  4. C知识要点-个人总结

    [数据结构]()C 结构体.C 共用体.C 数组.C 指针..... 存储类.auto.register.static.extern C 函数.定义函数.返回类型.函数名称.参数.函数主体.返回语句. ...

  5. mysql 将null转代为0(转)

    1.如果为空返回0 select ifnull(null,0) 2.如果为空返回0,否则返回1 select if(isnull(col),0,1) as col. MYSQL 中的IFNULL函数 ...

  6. Hibernate系列4-----之删除

    1.和它的增改查兄弟不同,多了个until包定义了HibernateUntil类,让我们来一起看看吧 public class HibernateUntil { private static Conf ...

  7. java虚拟机之GC(转)

    垃圾回收主要内容: 1. 那些内存需要回收? 2. 什么时候回收? 3. 如何回收? 垃圾回收主要针对运行时数据区那些区域? 运行时数据区的线程私有区域有:虚拟机栈,本地方法栈,程序计数器等: 栈中的 ...

  8. js获取文件上传进度

    js获取文件上传进度: <input name="file" id="FileUpload" type="file" /> &l ...

  9. vue-样式问题

    问题: 今天在用vue开发单页面应用的时候,遇到一个问题,在A页面,直接刷新,页面的布局样式之类的是没有问题的,不过在B页面跳转到A页面,那么A页面有一些样式就不是预期的效果. 发现解决问题: 用调试 ...

  10. thinkphp 创建数据对象之data方法

    创建数据对象:data()方法 1.功能:给模型对象$data赋值,将模型对象转化为数据对象 tip:模型对象与数据对象之间就差一个赋过值的$data; 2.方法:data()其源码如下: tip:源 ...