Tarjan WA on #33 求调TVT
查看原帖
Tarjan WA on #33 求调TVT
564732
TimSwn090306楼主2023/10/21 11:53

割边+bfs求树的直径

代码:

#include <bits/stdc++.h>
#define fe(x) ((x)&1?x+1:x-1)
using namespace std;
const int maxn=2e5+5;
const int inf=0x3f3f3f3f;
struct edge{
    int from,to,next;
}e0[maxn<<1],e1[maxn<<1];
int n,m,tot0,tot1,h0[maxn],h1[maxn],cut[maxn<<1],d[maxn];
int tim,cnt,dfn[maxn],low[maxn],state[maxn];
bitset <maxn> vis;
queue <int> q;
inline void addEdge0(int x,int y){
    e0[++tot0]=(edge){x,y,h0[x]};
    h0[x]=tot0;
}
inline void addEdge1(int x,int y){
    e1[++tot1]=(edge){x,y,h1[x]};
    h1[x]=tot1;
}
inline void tarjan(int x,int in){
    low[x]=dfn[x]=++tim;
    for (int i=h0[x];i;i=e0[i].next){
        int v=e0[i].to;
        if (!dfn[v]){
            tarjan(v,i);
            low[x]=min(low[x],low[v]);
            if (low[v]>dfn[x]) cut[i]=cut[fe(i)]=true;
        }else if (i!=fe(in)) low[x]=min(low[x],dfn[v]);
    }
}
inline void dfs(int x,int p){
    state[x]=p;
    for (int i=h0[x];i;i=e0[i].next){
        int v=e0[i].to;
        if (cut[i] || state[v]) continue;
        dfs(v,p);
    }
}
inline int bfs(int st){
    memset(d,inf,sizeof(d));
    vis.reset();
    d[st]=0;
    q.push(st);
    while (!q.empty()){
        int now=q.front();
        q.pop();
        if (vis[now]) continue;
        vis[now]=1;
        for (int i=h1[now];i;i=e1[i].next){
            int v=e1[i].to;
            if (d[v]>d[now]+1){
                d[v]=d[now]+1;
                q.push(v);
            }
        }
    }
    int maxx=st;
    for (int i=1;i<=cnt;i++) if (!maxx || d[i]>d[maxx]) maxx=i;
    return maxx;
}
int main(){
    scanf("%d%d",&n,&m);
    for (int i=1,x,y;i<=m;i++){
        scanf("%d%d",&x,&y);
        addEdge0(x,y);
        addEdge0(y,x);
    }
    for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i,0);
    for (int i=1;i<=n;i++) if (!state[i]) dfs(i,++cnt);
    // printf("%d\n",cnt);
    for (int i=1;i<=tot0;i++){
        int u=e0[i].from,v=e0[i].to;
        if (state[u]!=state[v]) addEdge1(state[u],state[v]);
    }
    int p=bfs(1);
    int q=bfs(p);
    printf("%d\n",d[q]);
    return 0;
}

(话说可以用割边写缩点吧

2023/10/21 11:53
加载中...