首页 > 其他分享 >AcWing3696 -- topsort & 贪心

AcWing3696 -- topsort & 贪心

时间:2023-03-27 13:11:33浏览次数:48  
标签:-- 拓扑 int edges AcWing3696 topsort op

1. 题目描述

给定我们一些有向边和无向边,判断在将所有无向边确定方向后,能否生成一个有向无环图



2. 思路

思路其实真的非常简单。
我根据题目给定的有向边做一次 \(topsort\),如果失败,说明无论剩下的无向边在怎么确定方向,都不可能无环。
如果成功,那么我们便成功确定了拓扑序。那么对于剩下的没有确定方向的边,我们按照拓扑序确定方向即可。此时,一定能构成有向无环图。
题目说了,给定的图不一定联通,事实上,不联通并不影响拓扑序,如果多个点之间不联通,那么他们的拓扑序是任意的。



3. 代码

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef pair<int, int> PII;
const int N = 200010, M = N, INF = 0x3f3f3f3f;

int T, n, m, k;
int h[N], e[M], ne[M], idx;
int d[N], q[N], pos[N];
PII edges[M];

bool topsort()
{
    int hh = 0, tt = -1;
    for(int i = 1; i <= n; i ++ )   
        if(!d[i])   q[ ++ tt ] = i;
    while(hh <= tt)
    {
        int t = q[hh ++ ];
        for(int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if( -- d[j] == 0)   q[ ++ tt ] = j;
        }
    }
    
    return tt == n - 1;
}

void add(int a, int b)
{
    d[b] ++ , e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}

int main()
{
    cin >> T;
    while(T -- )
    {
        cin >> n >> m;
        // init
        idx = 0;
        k = 0;
        memset(h, -1, sizeof(int) * (n + 10));
        memset(d, 0, sizeof(int) * (n + 10));
        
        for(int i = 0; i < m; i ++ )
        {
            int op, a, b;
            cin >> op >> a >> b;
            if(op)  add(a, b);
            else edges[k ++ ] = {a, b}; // store undirected edge
        }
        
        if(!topsort())  puts("NO");
        else 
        {
            puts("YES");
            // first print directed edges
            for(int i = 1; i <= n; i ++ )
                for(int j = h[i]; j != -1; j = ne[j])
                    cout << i << ' ' << e[j] << endl;
            // get top sort
            for(int i = 0; i < n; i ++ )    pos[q[i]] = i;
            // set direct for undirected edge
            for(int i = 0; i < k; i ++ )
            {
                auto [a,b] = edges[i];
                if(pos[a] > pos[b]) cout << b << ' ' << a << endl;
                else    cout << a << ' ' << b << endl;
            }
        }
        
    }
    return 0;
}

标签:--,拓扑,int,edges,AcWing3696,topsort,op
From: https://www.cnblogs.com/ALaterStart/p/17261194.html

相关文章

  • ESXi8.0+超微IPMI工具上新了,附命令行调风扇相关操作
    问题描述超微x10sdv主板,装了ESXi,结果找了一圈,没有发现直接能用的IPMI。正好这两天风扇太吵,想着要改一下风扇的配置。又找了一圈,正巧有结果了,记录下来。要注意,超微的主板I......
  • iOS经典游戏《疯狂喷气机》全球中文Android版正式发布
    这是世界顶级手机游戏开发商首次在全球版本中加入国内手机游戏平台,拉开了中国手机游戏领域与世界接轨的序幕。届时,各国版本中都包含乐逗平台,让全球玩家更便捷地交流互动,......
  • Bill Gates开启马桶再造计划 可提炼纯净饮用水
    公共卫生环境仍然是世界上最大的卫生问题之一。儿童的头号疾病杀手便是通过接触受污染粪便传染的。厕所的卫生环境,全球缺少厕所的状况,是一个很严重的问题。尤其在第三世......
  • 新型锂电池 充电速度比普通电池快120倍!
    一群韩国科学家,在蔚山现代科技研究所已经研发出了一种快速充电锂电池,比普通电池充电速度快30到120倍,这个团队相信他们可以最终可以推出少于一分钟能充满电动汽车的新型电池......
  • 数论--原根(循环群生成元)
    对于素数p,如果存在一个正整数1<a<p,使得a1,a2,…,ap−1模p的值取遍1,2,…,p−1的所有整数,称a是p的一个原根(primitiveroot),其实就是循环群的生成元。如果aj≡......
  • flink1.16连接hive2.3.9依赖报错
    Causedby:java.lang.ClassNotFoundException:org.apache.flink.table.gateway.api.endpoint.SqlGatewayEndpointFactory原来的导包依赖是:<groupId>org.apache.flink</gr......
  • Windows RT的桌面模式是一个累赘!
    【编者按】TomWarren是著名科技博客TheVerge的编辑,他上个月参加了IFA2012伯林国际消费电子会展,并亲自目睹了WindowsRT操作系统的庐山真面目。他认为微软在打造更好的触......
  • Windows 8新功能:可在Windows 8平台玩Xbox Games
    我们都知道,Xbox是微软一款游戏机的专有名词,因此微软最近推出的XboxGameson Windows服务困扰了不少人。这个服务将会在下个月伴随着Windows8的发布而推出,是一个专门针对......
  • 图论--网络流最大流问题
    问题表述:给定一幅图(n个结点,m条边),每一条边有一个容量,现在需要将一些物品从结点s(称为源点)运送到结点t(称为汇点),可以从其他结点中转,求最大的运送量。在介绍最大流问题的解决方法......
  • HTC将在9月19日召开发布会,可能发布更便宜的Android或Windows Phone 8手机
    八月末到九月这段时间可以说是非常热闹,各大手机厂商扎堆发布新品,一时间百花齐放。之前已经得到消息,摩托罗拉、诺基亚、亚马逊、苹果、RIM等厂商将会先后在接下来的九月里召......