首页 > 其他分享 >AtCoder Beginner Contest 285 D - Change Usernames(拓扑排序)

AtCoder Beginner Contest 285 D - Change Usernames(拓扑排序)

时间:2023-01-16 10:58:12浏览次数:71  
标签:AtCoder Usernames DAG Beginner int 拓扑 mp 顶点 排序

这题想到可以用map容器将string与一个端点下标对应,再建一个有向图,将问题转换成判断一个有向图是否有环

赛后补题网上搜如何判断图是否有环,学到了拓扑排序

拓扑排序是什么

图论中,拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列。且该序列必须满足下面两个条件:

  • 每个顶点出现且只出现一次。
  • 若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面。

有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说。

image

它是一个 DAG 图,那么如何写出它的拓扑排序呢?这里说一种比较常用的方法:

  1. 从 DAG 图中选择一个没有前驱(即入度为0)的顶点并输出。
  2. 从图中删除该顶点和所有以它为起点的有向边。
  3. 重复 1 和 2 直到当前的 DAG 图为空或当前图中不存在无前驱的顶点为止

image

于是,得到拓扑排序后的结果是 { 1, 2, 4, 3, 5 }。

通常,一个有向无环图可以有一个或多个拓扑排序序列。这是因为可能同时存在多个入度为0的结点,这时,先处理哪个都是可以的。

整段引用了这篇博客

参考代码
#include <bits/stdc++.h>
using namespace std;

const int N = 1e6 + 10;
vector<int> e[N];
map<string, int> mp;
int ind[N], cnt, t;
queue<int> q;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n;
    cin >> n;
    for (int i = 1; i <= n; i ++ )
    {
        string a, b;
        cin >> a >> b;
        if (mp.find(a) == mp.end()) mp[a] = ++ cnt;
        if (mp.find(b) == mp.end()) mp[b] = ++ cnt;
        e[mp[a]].push_back(mp[b]);
        ind[mp[b]] ++;
    }

    for (int i = 1; i <= cnt; i ++ )
        if (!ind[i]) q.push(i), t ++;

    while (!q.empty())
    {
        int u = q.front(); q.pop();
        for (auto &v : e[u])
        {
            ind[v] -= 1;
            if (!ind[v])
            {
                q.push(v);
                t ++;
            }
        }
    }

    if (t == cnt) cout << "Yes\n";
    else cout << "No\n";

    return 0;
}

标签:AtCoder,Usernames,DAG,Beginner,int,拓扑,mp,顶点,排序
From: https://www.cnblogs.com/Panmaru/p/17054867.html

相关文章

  • Atcoder ARC 061 题解
    C-ManyFormulas题意​ 给出一个长度为10的由数字组成的字符串,你可以把'+'插入到任意位置,将字符串分割,形成一个算式。你有很多分割的方案,现在你需要将所有出现的算式的......
  • AtCoder Beginner Contest 285
    A-EdgeChecker2(abc285a)题目大意给定如下一棵树。给定\(a,b(a<b)\),问两者是否有连边。解题思路观察数可发现其为二叉树,两者有连边当且仅当\(b=2a\)或\(b=2a......
  • Atcoder Regular Contest ARC 153 A B C D 题解
    点我看题A-AABCDDEFE一个beautifulnumber是形如这样的:\(S1S1S3S4S5S5S7S8S7\)。如果选定了\(S1\),后面的数有100000种选法,所以先求出答案的\(S1\)。假设现在我们要求出......
  • Atcoder Regular Contest ARC 153 A B C D 题解
    点我看题A-AABCDDEFE一个beautifulnumber是形如这样的:\(S1S1S3S4S5S5S7S8S7\)。如果选定了\(S1\),后面的数有100000种选法,所以先求出答案的\(S1\)。假设现在我们要求出......
  • Atcoder Regular Contest ARC 153 A B C D 题解
    点我看题A-AABCDDEFE一个beautifulnumber是形如这样的:\(S1S1S3S4S5S5S7S8S7\)。如果选定了\(S1\),后面的数有100000种选法,所以先求出答案的\(S1\)。假设现在我们要求出......
  • AtCoder Beginner Contest 254(C,D,E,F)
    AtCoderBeginnerContest254(C,D,E,F)CC这个题是给你一个乱序的数组,你可以把ai和ai+k进行交换,我们需要判断是否可以最后变成从小到大的顺序那么我们可以想到所有下标对k......
  • AtCoder Regular Contest 153
    喜提全场独一无二的score!ATC还是很友善的,如果每题等分就寄了A签到B真的是凭着实力不会做的呀。。。太菜了发现两维可以分别做,所以考虑一维的情况,然而并不会对于两......
  • Atcoder abc275F
    Atcoderabc275F题意:给出一个长度为\(n\)的数组\(A=(a_1​,a_2​,…,a_N)\),问是否能通过删掉一些子段使剩下的数之和为\(q\)。若可以,求出最小操作次数,否则输出−1......
  • AtCoder Beginner Contest 282 G - Similar Permutation
    套路题题意求有多少个\(1\)到\(n\)的排列满足恰有\(k\)对在排列中相邻的数满足前小于后\(2\leqn\leq500,0\leqk\leq(n-1)\)思路f[i][j][k]表示已经......
  • AtCoder Beginner Contest 134
    AtCoderBeginnerContest134https://atcoder.jp/contests/abc134A-Dodecagon#include<bits/stdc++.h>usingnamespacestd;intmain(){inta;cin......