• [CodeVS2822]爱在心中


    思路:
    Tarjan+缩点。
    首先跑一遍Tarjan,统计结点个数大于$1$的连通分量个数。然后寻找统计结点个数大于$1$且出度为$0$的连通分量,若只存在一个这样的连通分量,输出其点集即可。

     1 #include<stack>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<vector>
     5 inline int getint() {
     6     char ch;
     7     while(!isdigit(ch=getchar()));
     8     int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const int V=100001;
    13 std::vector<int> e[V];
    14 inline void add_edge(const int u,const int v) {
    15     e[u].push_back(v);
    16 }
    17 int dfn[V],low[V],scc[V],id=0,cnt=0;
    18 bool ins[V];
    19 std::stack<int> s;
    20 void Tarjan(const int x) {
    21     low[x]=dfn[x]=++cnt;
    22     s.push(x);
    23     ins[x]=true;
    24     for(unsigned i=0;i<e[x].size();i++) {
    25         int &y=e[x][i];
    26         if(!dfn[y]) {
    27             Tarjan(y);
    28             low[x]=std::min(low[x],low[y]);
    29         }
    30         else if(ins[y]) {
    31             low[x]=std::min(low[x],dfn[y]);
    32         }
    33     }
    34     if(dfn[x]==low[x]) {
    35         id++;
    36         int y=x;
    37         do {
    38             y=s.top();
    39             s.pop();
    40             ins[y]=false;
    41             scc[y]=id;
    42         } while(y!=x);
    43     }
    44 }
    45 int out[V]={0},size[V]={0};
    46 int main() {
    47     int n=getint();
    48     for(int m=getint();m;m--) {
    49         int u=getint(),v=getint();
    50         add_edge(u,v);
    51     }
    52     for(int i=1;i<=n;i++) {
    53         if(!dfn[i]) Tarjan(i);
    54     }
    55     for(int x=1;x<=n;x++) {
    56         size[scc[x]]++;
    57         for(unsigned i=0;i<e[x].size();i++) {
    58             int &y=e[x][i];
    59             if(scc[x]!=scc[y]) out[scc[x]]++;
    60         }
    61     }
    62     int ans1=0,cnt=0;
    63     std::vector<int> ans;
    64     for(int i=1;i<=id;i++) {
    65         if(size[i]>1) ans1++;
    66         if(out[i]) continue;
    67         if(size[i]==1) continue;
    68         cnt++;
    69         for(int j=1;j<=n;j++) {
    70             if(scc[j]==i) ans.push_back(j);
    71         }
    72     }
    73     printf("%d
    ",ans1);
    74     if(cnt==1) {
    75         for(unsigned i=0;i<ans.size();i++) {
    76             printf("%d ",ans[i]);
    77         }
    78     }
    79     else puts("-1");
    80     return 0;
    81 }
  • 相关阅读:
    URAL 1948 H
    int、long、long long取值范围
    Bonetrousle HackerRank 数学 + 思维题
    湖南省第十二届大学生计算机程序设计竞赛 problem A 2016
    Abbreviation ---- hackerrank
    POJ 3321 Apple Tree DFS序 + 树状数组
    HDU
    PICO CTF 2013 PHP 2: 85
    XSS进阶三
    XSS进阶二
  • 原文地址:https://www.cnblogs.com/skylee03/p/7399984.html
Copyright © 2020-2023  润新知