萌新刚学OI,求调程序
查看原帖
萌新刚学OI,求调程序
731650
_zuoqingyuan楼主2023/12/14 16:20

思路:tarjan+拓扑排序+dp,第12,13个测试点是WA

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int N=100010,M=1000010,inf=1e9+10;
int ver[N],to[N],nxt[N],idx,tmp[N],w[N][2],u[M/2],v[M/2],n,m,ans=0;
int dfn[N],low[N],scc,tot,stk[N],top,mk[N],f[N],d[N],dp[N][2];
bool pd[N][2];
void add(int x,int y){
    to[++idx]=y,nxt[idx]=ver[x],ver[x]=idx;
}
int cmp(int a,int b,int c){
    if(c==1)return min(a,b);
    else return max(a,b);
}
void tarjan(int u){
    dfn[u]=low[u]=++tot;
    stk[++top]=u,mk[u]=1;
    for(int i=ver[u];i;i=nxt[i]){
        int tp=to[i];
        if(!dfn[tp]){
            tarjan(tp);
            low[u]=min(low[u],low[tp]);
        }else if(mk[tp])low[u]=min(low[u],dfn[tp]);
    }
    if(dfn[u]==low[u]){
        int cnt1=-inf,cnt2=inf,tp;scc++;
        while(stk[top+1]!=u){
            tp=stk[top--];
            f[tp]=scc;
            mk[tp]=0;
            cnt1=max(cnt1,tmp[tp]);
            cnt2=min(cnt2,tmp[tp]);
        }
        w[scc][0]=cnt1,w[scc][1]=cnt2;
    }
    return;
}
void topsort(int s,int p){
    queue<int>q;
    q.push(f[s]),dp[f[s]][p]=w[f[s]][p];
    while(q.size()){
        int t=q.front();q.pop();
        for(int i=ver[t];i;i=nxt[i]){
            int tp=to[i];
            d[tp]--;pd[tp][p]=1;
            dp[tp][p]=cmp(dp[t][p],w[tp][p],p);
            if(!d[tp])q.push(tp);
        }
    }
    return;
}
int main(){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",tmp+i);
    }
    for(int i=1;i<=m;i++){
        int z;
        scanf("%d %d %d",u+i,v+i,&z);
        if(z==1)add(u[i],v[i]);
        else add(u[i],v[i]),add(v[i],u[i]);
    }
    for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
    memset(ver,0,sizeof(ver));memset(to,0,sizeof(to));memset(nxt,0,sizeof(nxt));idx=0;
    for(int i=1;i<=m;i++)if(f[u[i]]!=f[v[i]])add(f[u[i]],f[v[i]]),d[f[v[i]]]++;
    topsort(1,1);
    memset(ver,0,sizeof(ver));memset(to,0,sizeof(to));memset(nxt,0,sizeof(nxt));idx=0;
    for(int i=1;i<=m;i++)if(f[u[i]]!=f[v[i]])add(f[v[i]],f[u[i]]),d[f[u[i]]]++;
    topsort(n,0);
    pd[f[1]][1]=pd[f[1]][0]=pd[f[n]][1]=pd[f[n]][0]=1;
    for(int i=1;i<=scc;i++)if(pd[i][1]&&pd[i][0])ans=max(ans,dp[i][0]-dp[i][1]);
    cout<<ans<<endl;
    return 0;
}
2023/12/14 16:20
加载中...