질문 노트를 그래프 탐색 P3916를 수행 ++

식사 질문 후 오늘 브러시가, 갑자기 그런 문제가 자신의 작업 목록을보고, 쓰기를 열 것입니다.

표면 (N <= 10 ^ 5 m <= 10 ^ 5)는 DFS 생각 자연스러운는도 사용 벡터 메모리, I는 DFS 개의 방법을 생각 그래프를 트래버스하는 문제가 상기 :

모든 점 · DFS 있었다 각 지점의 경우, 각 시간 DFS 탐색을 달성 할 수 있으며, 최대 값이
방법은 매우 간단합니다, 매우 폭력적이지만, 문제는 각 포인트에 대한 최악의 경우 전체지도를 탐색 할 필요가 있다는 것입니다, 시간 복잡도 그것은이다 O (㎚)
· 최대 당신이 그것의 최대에이 점을 넣을 수없는 경우, 각 트래버스 점, DFS를 가리 키도록 첫째.
이 방법에 대한 최적화에 매우 큰 상대를 가지며, (A)의 값은 N, 난이 노드 각 액세스 포인트 시간을 각각의 액세스 포인트 (1)로부터 순환되고, (A)의 값이 가장 인 우수한 우리는 접합에 액세스 할 수있는 경우 다음 그 대답은 확실히 현재 큰 아니기 때문에. 이 방법의 시간 복잡도는 O (n 개에 + m) (바)는
코드를 구현 :

#include <cstdio>
#include <cctype>
#include <vector>
#define MAXN 100010
#define _for(i,a,b) for (int i = a;i <= b;i++)
#define _fd(i,a,b) for (int i = b;i >= a;i--)
using namespace std;
vector <int> G[MAXN];
int n,m,a[MAXN];

inline int read() {
    int a = 0,f = 1;
    char v= getchar();
    while (!isdigit(v)) {
        if (v == '-') {
            f = -1;
        }
        v = getchar();
    }
    while (isdigit(v)) {
        a = a * 10 + v - 48;
        v = getchar();
    }
    return a * f;
}

inline void addedge(int u,int v) {
    G[v].push_back(u);
}

void dfs(int x,int p) {
    if (a[x]) {
        return ;
    }
    a[x] = p;
    int vv = G[x].size();
    for (int i = 0;i < vv;i++) {
        dfs(G[x][i],p);
    }
}

int main() {
    n = read(),m = read();
    _for(i,1,m) {
        int u = read(),v = read();
        addedge(u,v);
    }
    _fd(i,1,n) {
        dfs(i,i);
    }
    _for(i,1,n) {
        printf("%d ",a[i]);
    }
    return 0;
}

나는이 문제에 대한 해결책을 볼 때 나중에 갑자기 Tarjan도 대답 할 수 발견!

Tarjan는 유니콤 구성 요소를 사용하여 얻은, 차이나 유니콤 (China Unicom) 내부의 각 구성 요소의 응답 점은 동일합니다!

코드 구현 (문제 해결)

#include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 
 7 const int maxn = 10e5 + 5;
 8 
 9 struct Edge{
10     int to,next;
11 }e[maxn];
12 
13 int dfn[maxn],low[maxn],Time;
14 int s[maxn],top,vis[maxn];
15 int f[maxn],n,m;
16 int cnt,belong[maxn],MAX[maxn];
17 int k,x[maxn],y[maxn],head[maxn];
18 
19 void add(int u,int v)
20 {
21     e[++k].to = v;
22     e[k].next = head[u];
23     head[u] = k;
24 }
25 
26 void tarjan(int x)                   //求有向图强联通分量的tarjan,在这里不过多叙述,想学习的可以点链接去博客qwq 
27 {
28     vis[x] = 1;
29     s[++top] = x;
30     dfn[x] = low[x] = ++Time;
31     for(int i = head[x];i;i=e[i].next)
32     {
33         int to = e[i].to;
34         if(!dfn[to])
35         {
36             tarjan(to);
37             low[x] = min(low[x],low[to]);
38         }
39         else if(vis[to])
40             low[x] = min(low[x],dfn[to]);
41     }
42     if(dfn[x] == low[x])            //如果x及其子树能够构成一个强联通分量 
43     {
44         ++cnt;
45         int j;
46         while(j=s[top])             //将其子树中的点都加入此分量中,并将此分量中的最大值保存在MAX数组中 
47         {
48             vis[j] = 0;
49             belong[j] = cnt;
50             MAX[cnt] = max(MAX[cnt],j);
51             top--;
52             if(j==x) break;
53         }
54     }
55 }
56 
57 void dfs(int x)                     //记忆化搜索 
58 {
59     if(f[x]) return;
60     f[x] = MAX[x];                  //当前强联通分量中的最大值 
61     for(int i=head[x];i;i=e[i].next)
62     {
63         int to = e[i].to;
64         if(!f[to]) dfs(to);
65         f[x] = max(f[x],f[to]);     // 子树中的最大值 
66     }
67 }
68 
69 int main()
70 {
71     //freopen("data.in","r",stdin);
72     //freopen("jkb.out","w",stdout);
73     scanf("%d%d",&n,&m);
74     for(int i=1;i<=m;i++)
75     {
76         scanf("%d%d",&x[i],&y[i]);          //保存边信息 
77         add(x[i],y[i]);
78     }
79     for(int i=1;i<=n;i++)                   //求出强联通分量 
80         if(!dfn[i])
81             tarjan(i);
82     memset(e,0,sizeof(e));                  //清空原图 
83     memset(head,0,sizeof(head));    
84     k = 0;
85     for(int i=1;i<=m;i++)                   //建立新图 
86         if(belong[x[i]]!=belong[y[i]])
87             add(belong[x[i]],belong[y[i]]);
88     for(int i=1;i<=cnt;i++)
89         if(!f[i]) dfs(i);
90     for(int i=1;i<=n;i++)                   //输出答案 
91         printf("%d ",f[belong[i]]);
92     return 0;
93 }

추천

출처www.cnblogs.com/doubeecat/p/10335591.html