P3916 图的遍历

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define de(x) cout<<x<<" ";
#define sf(x) scanf("%d",&x);
#define Pu puts("");
const int N=1e5+10;//targin做法
//targin作用:求连通量
int n,m;
int ans[N];

bool instack[N];
stack<int>st;
int dfn[N],low[N],tim;
int rep[N];//连通块中最大的编号
int tongkuai=0;
int belong[N];

int head[N],tot;
struct edge{
    int from,to;
    int nxt;
}e[N];
void add_edge(int u,int v){
    tot++;
    e[tot].from=u;e[tot].to=v;
    e[tot].nxt=head[u];
    head[u]=tot;
}
void targin(int x){
    dfn[x]=low[x]=++tim;
    instack[x]=1;
    st.push(x);
    for(int i=head[x];i;i=e[i].nxt){
        int to=e[i].to;
        if(dfn[to]==0){
            targin(to);//新建圈,不断向下找未访问过的点
            low[x]=min(low[x],low[to]);//子点已经更新,这个父点也要更新

        //已经没有点可以继续往下访问了
        }else if(instack[to]){//这个点已经被访问过
            low[x]=min(low[x],dfn[to]);
            //并且此时to点在栈中
        }
    }
    if(dfn[x]==low[x]){//这是精髓,当递归出来,兜兜转转又指向自己时,
    //说明一定存在强连通量,否则,low会继续递归,并向下指向其他的点
        tongkuai++;
        int tmp=st.top(); st.pop();
        while(tmp!=x){
            instack[tmp]=0;
            //标记联通块中所有的点为同一连通块
            belong[tmp]=tongkuai;
             //更新这一连通块中最大的编号
            rep[tongkuai]=max(rep[tongkuai],tmp);
            tmp=st.top();st.pop();
        }
        instack[x]=0;
        belong[x]=tongkuai;
        rep[tongkuai]=max(rep[tongkuai],x);
    }
}
void dfs(int x){
    if(ans[x]) return ;
    ans[x]=rep[x];
    for(int i=head[x];i;i=e[i].nxt){
        int to=e[i].to;
        if(!ans[x]) dfs(to);
        ans[x]=max(ans[x],ans[to]);
    }
}
int main(){
    cin>>n>>m;
    int u,v;
    for(int i=1;i<=m;i++){
        sf(u)sf(v)
        add_edge(u,v);
    }

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

    memset(head,0,sizeof(head));
    tot=0;//连通块之间建立新图
    for(int i=1;i<=m;i++){
        u=e[i].from;v=e[i].to;
        if(belong[u]==belong[v]) continue;
        //de(belong[u])de(belong[v])Pu
        add_edge(belong[u],belong[v]);
    }
    for(int i=1;i<=tongkuai;i++){
        if(!ans[i]) dfs(i);
    }
    //for(int i=1;i<=n;i++){de(belong[i])de(rep[belong[i]])de(ans[belong[i]]) Pu}
    for(int i=1;i<=n;i++){
        printf("%d ",ans[belong[i]]);
    }
    return 0;

}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define de(x) cout<<x<<" ";
#define sf(x) scanf("%d",&x);
#define Pu puts("");
const int N=1e5+10;//bfs做法
int n,m;
vector<int>v[N];//这里vector可以用head[]数组+edge[]数组表示
int ans[N];
void bfs(int t,int u){
    queue<int>q;
    q.push(t);
    while(q.size()){
        int nw=q.front();q.pop();
        ans[nw]=u;
        for(int i=0;i<v[nw].size();i++){
            if(ans[v[nw][i]]==0) q.push(v[nw][i]);
        }
    }
}
int main(){
    cin>>n>>m;
    int x,y;
    for(int i=1;i<=m;i++){
        sf(x)sf(y)
        v[y].push_back(x);
    }
    for(int i=n;i>=1;i--){
        if(ans[i]==0)
        bfs(i,i);
    }
    for(int i=1;i<=n;i++){
        printf("%d ",ans[i]);
    }Pu;
    return 0;

}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define de(x) cout<<x<<" ";
#define sf(x) scanf("%d",&x);
#define Pu puts("");
const int N=1e5+10;//dfs做法
int n,m;
vector<int>v[N];
int ans[N];
void dfs(int t,int u){
    if(ans[t]) return ;
    ans[t]=u;
    for(int i=0;i<v[t].size();i++){
        dfs(v[t][i],u);
    }
}
int main(){
    cin>>n>>m;
    int x,y;
    for(int i=1;i<=m;i++){
        sf(x)sf(y)
        v[y].push_back(x);
    }
    for(int i=n;i>=1;i--){
        dfs(i,i);
    }
    for(int i=1;i<=n;i++){
        printf("%d ",ans[i]);
    }Pu;
    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值