Niuke.com Wannafly Challenge 14 C. Accessibility (tarjan shrink point)

Link: https://www.nowcoder.com/acm/contest/81/C
Source : Niuke.com

Time limit: C/C++ 1 second, other languages ​​2 seconds
Space limit: C/C++ 262144K, other languages ​​524288K
64bit IO Format: %lldTitle
description
Given a directed graph with 0 ≤ N ≤ 105 points and 0 ≤ M ≤ 105 edges,
output a set of points as small as possible, so that any point can be reached from these points, if there are many For such sets, output the sets with the smallest lexicographical order after sorting them in ascending order.
Input description:

The first line contains two integers 1 ≤ n, m ≤ 105, and the
next M lines, each line contains two integers 1 ≤ u, v ≤ 105, indicating that there is a directed edge from point u to point v.
The data is guaranteed to have no double edges and self-loops.

Output description:

The first line outputs an integer z, representing the size of the point set as the answer;
the second line outputs z integers, sorted in ascending order, representing the point set as the answer.

Example 1
Input

7 10
4 5
5 1
2 5
6 5
7 2
4 2
1 2
5 3
3 5
3 6

Output

2
4 7

Analysis: First of all, all points whose in-degree is 0 must be put into the set, otherwise it will not be optimal. After excluding these points, in the graph composed of the remaining points, if there is no point with an in-degree of 0, there must be a ring. The ring is shortened, and the number of the smallest point in the ring is used as its number, and a new in-degree is found. Points with degree 0 are put into the set.

code show as below:

#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
const int MAXN=1e5+100;
int dfn[MAXN],low[MAXN],vis[MAXN];
int in[MAXN];
int root[MAXN];
vector<int>path[MAXN];
vector<int>ans;
stack<int>S;
int n,m,u,v,tot;
struct node
{
    you and;
    int v;
}edge[MAXN];
void tarjan(int x)
{
    low[x]=dfn[x]=++tot;
    S.push(x);vis[x]=1;
    for(int i=0;i<path[x].size();i++)
    {
       int v=path[x][i];
       if(!dfn[v])
       {
           Tarjan (v);
           low[x]=min(low[x],low[v]);
       }
       else  if (vis [v])
           low[x]=min(low[x],low[v]);
    }

    if(low[x]==dfn[x])
    {
       while(!S.empty())
       {
          int now=S.top();
          root[now]=x;
          vis[now]=0;
          S.pop();
          if(now==x)break;
       }
    }
}

intmain ()
{
    to = 0 ;
    scanf("%d%d",&n,&m);
    for(int k=1;k<=m;k++)
    {
     scanf("%d%d",&u,&v);
     edge[k].u =u,edge[k].v= v;
     path[u].push_back(v);
    }

    for(int i=1;i<=n;i++)
    {
      if(!dfn[i])
      Tarjan (i);
    }

    for(int i=1;i<=m;i++)
    {
    if(root[edge[i].u]!=root[edge[i].v])
    in[root[edge[i].v]]++;
    }
    for(int i=1;i<=n;i++)
    {
       int r=root[i];
       if(in[r]==0)
        ans.push_back(r);

    }
    sort(ans.begin(),ans.end());
    ans.erase(unique(ans.begin(),ans.end()),ans.end());
    cout<<ans.size()<<endl;
    for(int i=0;i<ans.size();i++)
    i==0?cout<<ans[i]:cout<<" "<<ans[i];
    cout<<endl;
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324976604&siteId=291194637