求助:Tarjan+DP TLE了三个点
查看原帖
求助:Tarjan+DP TLE了三个点
365236
岚默笙楼主2020/10/29 15:04
#include<bits/stdc++.h>
using namespace std;
#define maxn 100100
#define maxm 500010
int head[maxn];
int v[maxn];
int tot=0;
bool ins[maxn];
int cnt=0;
int sd[maxn];
int valm[maxn];
int valn[maxn];
bool con[maxn];
stack<int> s;
struct edge
{
    int nxt[maxm],to[maxm],from[maxm];
    void add(int x,int y)
    {
        to[++tot]=y;
        from[tot]=x;
        nxt[tot]=head[x];
        head[x]=tot;
    }
}e1,e2;
int dfn[maxn],low[maxn],tim=0;
void tarjan(int x)
{
    dfn[x]=low[x]=++tim;
    ins[x]=1;
    s.push(x);
    for(int i=head[x];i;i=e1.nxt[i])
    {
        int y =e1.to[i];
        if(!dfn[y])
        {
            tarjan(y);
            low[x]=min(low[x],low[y]);
        }
        else if(ins[y])
            low[x]=min(low[x],dfn[y]);
    }
    if(dfn[x]==low[x])
    {
        int cur;
        ++cnt;
        valn[cnt]=10000000000;
        do
        {
            cur = s.top();
            s.pop();
            ins[cur]=0;
            sd[cur]=cnt;
            valn[cnt]=min(valn[cnt],v[cur]);
            valm[cnt]=max(valm[cnt],v[cur]);
        } while (x!=cur);
        
    }
}
int ss,ee;
void dfs1(int x)
{
    for(int i=head[x];i;i=e2.nxt[i])
    {
        int y =e2.to[i];
        dfs1(y);
        con[x]+=con[y];
    }
}
int mn[maxn],mx[maxn];
int ans=0;
void dfs2(int x)
{
    for(int i=head[x];i;i=e2.nxt[i])
    {
        int y = e2.to[i];
        if(!con[y]) continue;
        mn[y] = min(mn[x],valn[y]);
        dfs2(y);
        mx[x] = max(mx[y],valm[x]);
    }
    ans = max(ans,mx[x]-mn[x]);
}
int n,m;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    scanf("%d",&v[i]);
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        e1.add(x,y);
        if(z==2)
        e1.add(y,x);
    }
    for(int i=1;i<=n;i++)
    {
        if(!dfn[i])
        tarjan(i);
    }
    ss=sd[1];
    ee=sd[n];
    con[ss]=con[ee]=1;
    int tot1=tot;
    tot=0;
    memset(head,0,sizeof(head));
    for(int i=1;i<=tot1;i++)
    {
        int x = sd[e1.from[i]], y = sd[e1.to[i]];
        if(x!=y)
        e2.add(x,y);
    }
    dfs1(ss);
    mn[ss]=valn[ss];
    mx[ee]=valm[ee];
    dfs2(ss);
    printf("%d",ans);   
    return 0;
}
2020/10/29 15:04
加载中...