洛谷 3916 图的遍历

Posted Driver_Lao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 3916 图的遍历相关的知识,希望对你有一定的参考价值。

【题解】

  先用Tarjan缩环,然后重新建图并在图上跑dfs+DP

  

// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#include<cstring>
#define rg register
#define N 200010
using namespace std;
int n,m,tot,top,color,ans[N],last[N],col[N],mx[N],dfn[N],low[N],st[N],r[N][2];
bool vis[N];
struct edge{int to,pre;}e[N];
inline int read(){
    int k=0,f=1;char c=getchar();
    while(c<\'0\'||c>\'9\')c==\'-\'&&(f=-1),c=getchar();
    while(\'0\'<=c&&c<=\'9\')k=k*10+c-\'0\',c=getchar();
    return k*f;
}
inline void add(int x,int y){e[++tot]=(edge){y,last[x]}; last[x]=tot;}
inline int max(int x,int y){return x>y?x:y;}
void tarjan(int x){
	dfn[st[++top]=x]=low[x]=++tot;
	for(rg int i=last[x],to;i;i=e[i].pre)
		if(!dfn[to=e[i].to]) tarjan(to),low[x]=min(low[x],low[to]);
		else if(!col[to]) low[x]=min(low[x],dfn[to]);
	if(dfn[x]==low[x]) 
		for(color++;st[top+1]!=x;top--) col[st[top]]=color,mx[color]=max(mx[color],st[top]);
}
void dfs(int x){
    vis[x]=1;
    for(rg int i=last[x],to;i;i=e[i].pre){
        if(!vis[to=e[i].to]) dfs(to);
        mx[x]=max(mx[x],mx[to]);
    }
}
int main(){
    n=read(); m=read();
    for(rg int i=1;i<=m;i++) r[i][0]=read(),add(r[i][0],r[i][1]=read());
    tot=0;
    for(rg int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
    tot=0; memset(last,0,sizeof(last));
    for(rg int i=1;i<=m;i++)
    	if(col[r[i][0]]!=col[r[i][1]]) add(col[r[i][0]],col[r[i][1]]);
    for(rg int i=1;i<=color;i++) if(!vis[i]) dfs(i);
    for(rg int i=1;i<=n;i++) printf("%d ",mx[col[i]]);
    return 0;
}

  

以上是关于洛谷 3916 图的遍历的主要内容,如果未能解决你的问题,请参考以下文章

P3916 图的遍历 反向建图+DFS

图的遍历(某谷P3916)

图的遍历

ACM入门之图论习题

求图的深度优先遍历程序 c语言版

图的深度优先遍历DFS和广度优先遍历BFS(邻接矩阵存储)超详细完整代码进阶版