非常规做法 80分求调
查看原帖
非常规做法 80分求调
241838
microchip楼主2024/5/11 17:30

做法:tarjan缩点,但是不用拓扑而是dfs,这么做有bug吗

#include<bits/stdc++.h>
using namespace std;
 
struct edge{
    int from,to;
}ed[1000050];
 
int n,m,v[100050],x,y,z,dfn[100050],low[100050],kth,scc[100050],nth,cnt,mx[100050],mn[100050],maxn[100050],minn[100050],ans;
int st[100050],tp;
bool flag[100050],can_arrive[100050];
vector<int> T[100050],new_T[100050];
queue<int> q;
 
void dfs(int no){
    dfn[no]=low[no]=++kth;
    st[++tp]=no;
    for(unsigned int i=0;i<T[no].size();i++){
        if(dfn[T[no][i]]==0){
            dfs(T[no][i]);
            low[no]=min(low[no],low[T[no][i]]);
        }else low[no]=min(low[no],dfn[T[no][i]]);
    }if(dfn[no]==low[no]){
        nth++;
        while(st[tp]!=no){
            scc[st[tp]]=nth;
            mx[nth]=max(mx[nth],v[st[tp]]);
            mn[nth]=min(mn[nth],v[st[tp]]);
            tp--;
        }scc[st[tp]]=nth;
        mx[nth]=max(mx[nth],v[st[tp]]);
        mn[nth]=min(mn[nth],v[st[tp]]);
        tp--;
    }
}
 
void dfs2(int no){
    minn[no]=min(minn[no],mn[no]);
    maxn[no]=max(maxn[no],mx[no]);
    flag[no]=1;
    if(no==scc[n]){
        can_arrive[no]=1;
        return;
    }
    for(unsigned int i=0;i<new_T[no].size();i++){
        if(flag[new_T[no][i]]==0){
            dfs2(new_T[no][i]);
            if(can_arrive[new_T[no][i]]){
                can_arrive[no]=1;
                maxn[no]=max(maxn[no],maxn[new_T[no][i]]);
                minn[new_T[no][i]]=min(minn[new_T[no][i]],minn[no]);
            }
        }
    }
}
 
int main()
{
    memset(mn,0x7f,sizeof(mn));
    memset(minn,0x7f,sizeof(mn));
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>v[i];
    for(int i=1;i<=m;i++){
        cin>>x>>y>>z;
        T[x].push_back(y);
        cnt++;
        ed[cnt].from=x;
        ed[cnt].to=y;
        if(z==2){
            T[y].push_back(x);
            cnt++;
            ed[cnt].from=y;
            ed[cnt].to=x;
        }
    }for(int i=1;i<=n;i++)
        if(dfn[i]==0)dfs(i);
    for(int i=1;i<=cnt;i++)
        if(scc[ed[i].from]!=scc[ed[i].to])
            new_T[scc[ed[i].from]].push_back(scc[ed[i].to]);
    dfs2(scc[1]);
    for(int i=1;i<=nth;i++)
        if(can_arrive[i])ans=max(ans,maxn[i]-minn[i]);
    cout<<ans<<endl;
    return 0;
}

2024/5/11 17:30
加载中...