hiho拓扑排序专题 ——第四十八、四十七周

拓扑排序·一

分析:

此题就是求一个有向图中是否存在环。 如存在环则输出"Wrong", 若不存在环, 说明课程安排的合理,输出"Correct"。

题中的提示说的已经十分清楚了。

总的来说就是

① 找出入度为0的点(说明该点没有前驱),把该点放入集合T中。 把所有从该点出发的边都删除;

② 遍历剩余的点, 找出入度为0 的点, 重复①操作。

③直到不存在入度为0的点。 结束。如果此时集合T中包含所有的点, 那么该图不存在环, 否则存在环。

注意:1、执行操作①时, 在删除边时(u, v),同时更新与其相关点的入度(du[v]--);

2、 在执行操作②时, 需要遍历所有点, 点少的时候可行, 点多的话很容易超时。 所以题目的提示中告诉了一个好办法就是: 执行操作①更新相关点的入度时直接判断一下是否为0, 若为零则入队列。 这样会省很多时间。

如下图例子:

开始点1入度为0, 点1加入集合T,   删除从1出发的边;  更新相关点的入度, 点2、3的入度都变为0了 , 2、3入队列;

再依次对点2、3进行①操作, 2、3加入T,   删除边(2, 4), (3, 4), 此时没有其他点入度为0了, 结束操作, T中未包含所有点, 说明该图中有环;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;

int t, n, m, sum, du[100005];
vector<int> vec[100005];

int ac()
{
    queue<int> q;
    for(int i = 1; i <= n; i++)//遍历一边所有点, 把入度为0的点,全加入队列q中
    {
        if(du[i] == 0)
            q.push(i);
    }
    while(!q.empty())
    {
        int tem = q.front();//在队列中取出一个入度为0的点
        q.pop();
        sum++;
        //把所有从tem出发的边(tem, v)删除并更新du[],
        for(int i = 0; i < vec[tem].size(); i++)
        {
            du[vec[tem][i]]--;
            if(du[vec[tem][i]] == 0)//若点vec[tem][i]入度更新后为0, 则入队列
                q.push(vec[tem][i]);
        }
        vec[tem].clear();
    }
    if(sum == n) return 1;
    else
        return 0;
}
int main()
{
    cin >> t;
    while(t--)
    {
        scanf("%d%d", &n, &m);
        //用vec[]来存边
        for(int i = 1; i <= n; i++) vec[i].clear();
        memset(du, 0, sizeof(du));//初始化入度, 置为0;
        for(int i = 1; i <= m; i++)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            vec[x].push_back(y); // 加入边
            du[y]++; //记录入度
        }
        sum = 0;
        int ans = ac();
        if(ans == 1)
            printf("Correct\n");
        else
            printf("Wrong\n");
    }
    return 0;
}

拓扑排序·二

分析:

和上一道差不多, 只是多了一项就是记录每个点的病毒数。  每个点的病毒数 = 自身病毒数 +  所有能够达到它的节点病毒数之和( 就是所有它前驱点的病毒数的和)。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int mod = 142857;
int n, m, k, sum, virus[100005], du[100005];
vector<int> vec[100005];

void ac()
{
    queue<int> q;
    for(int i = 1; i <= n; i++)
    {
        if(du[i] == 0)
            q.push(i);
    }
    while(!q.empty())
    {
        int tmp = q.front(); q.pop();
        sum = (sum + virus[tmp]) % mod;  

        //把所有前驱点为 tmp 的点的病毒数都加上 tmp的病毒数
        for(int i = 0; i < vec[tmp].size(); i++)
        {
            int b = vec[tmp][i];
            virus[b] = (virus[tmp] + virus[b]) % mod;// 此处也一定要取模,
            du[b]--;
            if(du[b] == 0)
                q.push(b);
        }
        vec[tmp].clear();
    }
}
int main()
{
    while(scanf("%d%d%d", &n, &m, &k) != EOF)
    {
        memset(virus, 0, sizeof(virus));
        memset(du, 0, sizeof(du));
        for(int i = 1; i <= n; i++) vec[i].clear();

        for(int i = 1; i <= k; i++)
        {
            int x;
            scanf("%d", &x);
            virus[x]++;
        }
        for(int i = 1; i <= m; i++)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            vec[x].push_back(y);
            du[y]++;
        }

        sum = 0;
        ac();
        printf("%d\n", sum);
    }
    return 0;
}
时间: 2024-10-13 23:14:54

hiho拓扑排序专题 ——第四十八、四十七周的相关文章

QT开发(四十八)——数据库SQL接口层

QT开发(四十八)--数据库SQL接口层 SQL接口层提供了对数据库的访问,主要类包括Qt SQL模块中的QSqlDatabase.QSqlQuery.QSqlError.QSqlField.QSqlIndex和QSqlRecord.QSqlDatabase类用于创建数据库连接,QSqlQuery用于使用SQL语句实现与数据库交互. 一.QSqlDatabase 1.QSqlDatabase简介 QSqlDatabase类提供了通过连接访问数据库的接口,QSqlDatabase对象本身代表一个连

你的一天也可以是四十八小时

只要你愿意,你的一天将是四十八小时,而不是二十四小时. 时间就是上帝给你的资本.命运之神是公平的,他给每个人的时间都是公平的,他给每个人的时间都不多不少:但成功女神却是挑剔的,她只让那些能把24小时变成48小时的人接近她.下面就是她的助手时间使者透露出来的成功秘笈: 直奔主题 聪明人要远离琐碎,保持焦点.由于我们一次只能踏上一条船,“船”的选择便显得格外重要.为此,经济学家告诉我们,要保持焦点:一次只做一件事情,一个时期只有一个重点.西屋电脑公司总经理迪席勒办公室门上的标语是:“不要带问题给我,

产品定位四十八招(12)定位盈利专家吴玉龙

第四十招:基于"专用"定位策略<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 广告语"就像刚刚步出美发厅"定位"美发厅的选择"牌是美发厅专用的一种洗发香波. 第四十一招:"一次性使用"定位策略 1987年,柯达公司推出一次性相机获得了巨大的成功.1993年,仅在美国就销售了930万个一次性相

ActionScript3游戏中的图像编程(连载四十八)

总目录:http://blog.csdn.net/iloveas2014/article/details/38304477 3.1.4 简单滤镜中的渐变原理探讨 我们再简单的看一下滤镜里的渐变条. 为了尽可能地减少复杂的文字轮廓所造成的干扰,我再次使用方块进行试验. 我画了一个紫色的方块(啥颜色其实都无所谓了),然后添加渐变发光滤镜,把模糊和距离值都调大,以便看清楚渐变的轮廓,然后给渐变条随意地加上几种颜色(图 3.30) 图 3.30 模糊范围较大的渐变发光 可以看到,渐变条上的色彩从右往左地

【科普】江户四十八手图文最详细解释

完整预览图: 四十八手解説 [日本語]:http://hp.vector.co.jp/authors/VA044354/japaneseindetail.html 较难招式须注意安全: 虽然招式号称48招,不过就连推出教战手册的旅馆业者也认为,一般人试个三.五招其实就差不多了: 而且其中有些动作还属于[超高难度]级 比方说25招[搥衣棒],女方抱住两腿膝盖后侧,下半身直直往头顶举,男方则以相反方向由上向下顶. 还有27招[推车],男方站着将女方双脚抬起来,女方用双手撑在床面,身体成四十五度悬在空

JavaWeb学习总结(四十八)——模拟Servlet3.0使用注解的方式配置Servlet

JavaWeb学习总结(四十八)——模拟Servlet3.0使用注解的方式配置Servlet 一.Servlet的传统配置方式 在JavaWeb开发中, 每次编写一个Servlet都需要在web.xml文件中进行配置,如下所示: 1 <servlet> 2 <servlet-name>ActionServlet</servlet-name> 3 <servlet-class>me.gacl.web.controller.ActionServlet</s

实验四十八微软应用程序虚拟化之三APP-V 5.1 Client部署和通过组策略自定义配置

实验四十八微软应用程序虚拟化之三APP-V 5.1Client部署和通过组策略自定义配置 APP-V  Client分为Application Virtualization Desktop Client和 Application Virtualization Client for Remote Desktop Services,两者都为虚拟化应用程序提供并管理虚拟环境,管理到缓存的程序包传输.发布刷新.传输,以及与 Application Virtualization Server的所有交互.

2018-09-08 第四十、四十一次课

第四十.四十一次课 Docker入门 目录 一. docker简介 二. 安装docker 三. 镜像管理 四. 通过容器创建镜像 五. 通过模板创建镜像 六. 容器管理 七. 仓库管理 八. 数据管理 九. 数据卷备份恢复 十. docker网络模式 十一. opration not permitted 十二. 配置桥接网络 十三. Dockerfile格式 十四. Dockerfile示例(安装nginx) 十五. 用docker compose部署服务 十六. docker compose

hiho一下 第四十八周 拓扑排序&#183;二【拓扑排序的应用 + 静态数组 + 拓扑排序算法的时间优化】

题目1 : 拓扑排序·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho所在学校的校园网被黑客入侵并投放了病毒.这事在校内BBS上立刻引起了大家的讨论,当然小Hi和小Ho也参与到了其中.从大家各自了解的情况中,小Hi和小Ho整理得到了以下的信息: 校园网主干是由N个节点(编号1..N)组成,这些节点之间有一些单向的网路连接.若存在一条网路连接(u,v)链接了节点u和节点v,则节点u可以向节点v发送信息,但是节点v不能通过该链接向节点u发送信息. 在刚