• [CF825E] Minimal Labels(反向建图,拓扑排序)


    题目链接:http://codeforces.com/problemset/problem/825/E

    题意:给一个有向图,求一个排列,这个排列是每一个点的序号,使得序号对应的点的排序符合拓扑序并且这个排列字典序最小。

    直接跑字典序最小的拓扑排序是不行的,因为那样只是确保点的字典序而非这个排列的字典序,比如这个数据:

    10 1
    5 2

    反过来考虑,点号大的入度为0的点一定排在后面,这个位置确定了。但是点好小的入度为0的未必一定排在前面,因为这个点之前可能有入度不为0,但是与此点无关的点在前面,按题意这种点是要比当前点的序号小的。

    反向建图,跑字典序最大的拓扑排序就行了。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 100100;
     5 int n, m, cnt;
     6 vector<int> G[maxn];
     7 int ret[maxn], in[maxn];
     8 priority_queue<int> pq;
     9 
    10 void init() {
    11     cnt = n;
    12     memset(in, 0, sizeof(in));
    13     while(!pq.empty()) pq.pop();
    14     for(int i = 0; i < maxn; i++) G[i].clear();
    15 }
    16 
    17 signed main() {
    18     // freopen("in", "r", stdin);
    19     int u, v;
    20     while(~scanf("%d%d",&n,&m)) {
    21         init();
    22         for(int i = 0; i < m; i++) {
    23             scanf("%d%d",&u,&v);
    24             G[v].push_back(u);
    25             in[u]++;
    26         }
    27         for(int i = 1; i <= n; i++) {
    28             if(!in[i]) pq.push(i);
    29         }
    30         while(!pq.empty()) {
    31             int u = pq.top(); pq.pop();
    32             ret[u] = cnt--;
    33             for(auto v : G[u]) {
    34                 in[v]--;
    35                 if(in[v] == 0) pq.push(v);
    36             }
    37         }
    38         for(int i = 1; i <= n; i++) {
    39             printf("%d%c", ret[i], i==n?'
    ':' ');
    40         }
    41     }
    42     return 0;
    43 }
  • 相关阅读:
    YASKAWA电机控制(1)---接线
    Linux使用者管理(2)---账号管理
    OpenCV源码阅读(3)---base.hpp
    机器视觉基础(2)---坐标与矩阵变换
    Linux使用者管理(1)---用户账号
    OpenCV源码阅读(3)---matx.h---学习心得
    OpenCV源码阅读(2)---matx.h---函数的内联实现
    机器视觉基础(1)---投影
    shell编程基础(5)---循环指令
    HTML里 iframe跳转后关闭iframe
  • 原文地址:https://www.cnblogs.com/kirai/p/7349954.html
Copyright © 2020-2023  润新知