P3916 图的遍历

题目传送门

今晚闲游洛谷,在图论中发现了这独树一帜的记忆化搜索。看到这道题,第一感受就是DFS,每一个点DFS一遍,如果能更新就更新,但是这样的时间复杂度是O(nm),对于1N,M105的数据显然是承受不住的,会T飞掉~

究其原因,是因为不断地更新,浪费了大量的时间。有没有改进的方法???答案是肯定的。

反向建边

反向建边可以让我们直接从最大的搜,只要最大的能搜到的一定都可以走到最大的,它的答案自然也就是最大的了,之后也就无需进行更新了,然后从最大的往小搜,可以达到下界O(n);

参考程序如下:

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 int maxn[100001],n,m,v[100001],nxt[100001],head[100001],total,b1,b2,x,y;
 5 void add()
 6 {
 7     cin>>b1>>b2;
 8     total++;
 9     nxt[total]=head[b2];
10     head[b2]=total;
11     v[total]=b1;
12 }
13 void dfs(int now,int begin)
14 {
15     if(maxn[now])return;
16     maxn[now]=begin;
17     for(int i=head[now];i!=-1;i=nxt[i])
18     {
19         dfs(v[i],begin);
20     }
21 } 
22 int main()
23 {
24     memset(head,-1,sizeof(head));
25     cin>>n>>m;
26     for(int i=1;i<=m;i++)
27     {
28         add();
29     }
30     for(int i=n;i>=1;i--)
31     {
32         dfs(i,i);
33     }
34     for(int i=1;i<=n;i++)cout<<maxn[i]<<" ";
35     cout<<endl;
36 }
View Code

  

原文地址:https://www.cnblogs.com/szmssf/p/10999932.html