一眼看过去
能往回走,各种图论算法肯定是不能直接用的,但是既然能回到自己,那就是说连通块里的每个点先后顺序随便,所以tarjan缩点搞一搞+DAG图dp
然后中间脑抽,啊,DAG图不就是一棵树吗,所以搞个dfs,记录一下爸爸,线性dp!
果然是太久没写dag图dp了……DAG图是一棵有向树,性质和树不完全相同,不能这么搞的
所以正解应该是tarjan缩点+top排序+树形dp
/*
作者:wyf
日期:2019/11/12
OJ:luogu
题目:1063
*/
#include<bits/stdc++.h>
#define maxn 4005010
#define ll long long
#define INF 2147483648
using namespace std;
int n,m;
struct edge
{
int next,end;
}e[maxn],new_e[maxn];
int head[maxn];
int tot;
void add(int x,int y)
{
e[++tot].next=head[x];
e[tot].end=y;
head[x]=tot;
}
int step=0;
int color=0;
int belong[maxn];
bool vis[maxn];
int stck[maxn];
int top;
int dfn[maxn],low[maxn];
void tarjan(int now)
{
dfn[now]=++step;
vis[now]=true;
low[now]=step;
stck[++top]=now;
for (int i=head[now];i;i=e[i].next)
{
int to=e[i].end;
if (!dfn[to])
tarjan(to),low[now]=min(low[to],low[now]);
else if (!belong[to])
low[now]=min(low[now],dfn[to]);
}
if (low[now]==dfn[now])
{
belong[now]=++color;
while(stck[top]!=now)
{
belong[stck[top]]=color;
top--;
}
top--;
}
}
int new_head[maxn];
int new_tot;
void new_add(int x,int y)
{
new_e[++tot].next=new_head[x];
new_e[tot].end=y;
new_head[x]=tot;
}
int rd[maxn];
int l,r;
int q[maxn];
void tp_sort()
{
r=0;
l=r;
for(int i=1;i<=color;i++)
if(!rd[i])
q[++r]=i;
while(l<r)
{
int x=q[++l];
for(int i=new_head[x];i;i=new_e[i].next)
{
int y=new_e[i].end;
rd[y]--;
if(!rd[y])
q[++r]=y;
}
}
// for (int i=1;i<=color;i++)
// cout<<q[i]<<' ';
}
int ed;
int xiao[maxn];
int fa[maxn];
int minn[maxn],maxx[maxn];
int f[maxn];
void dp()
{
for (int i=1;i<=color;i++)
{
// cout<<q[i]<<' '<<xiao[q[i]]<<" ";
for (int j=new_head[q[i]];j;j=new_e[j].next)
{
int to=new_e[j].end;
// cout<<to<<" ";
xiao[to]=min(min(xiao[to],xiao[q[i]]),minn[to]);
f[to]=max(max(f[to],f[q[i]]),maxx[to]-xiao[to]);
}
// cout<<endl;
}
// for (int i=1;i<=color;i++)
// cout<<xiao[q[i]]<<' '<<maxx[q[i]]<<' '<<f[q[i]]<<endl;
}
int a[maxn];
queue<int> qq;
/*void dfss(int now)
{
if (now==belong[1])
{
cout<<"ha";
while(!qq.empty())
{
cout<<qq.front()<<' ';
qq.pop();
}
return;
}
for (int i=new_head[now];i;i=new_e[i].next)
{
qq.push(i);
dfss(new_e[i].end);
qq.pop();
}
}*/
int main()
{
//freopen("ha.in","r",stdin);
//freopen("ha.out","w",stdout);
cin>>n>>m;
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
int cnt=m;
for (int i=1;i<=m;i++)
{
int ha,hb,k;
scanf("%d%d%d",&ha,&hb,&k);
if (k==2)
add(ha,hb),add(hb,ha),cnt++;
else
add(ha,hb);
}
for (int i=1;i<=n;i++)
if (!belong[i])
tarjan(i);
/* for (int i=1;i<=n;i++)
cout<<belong[i]<<' ';
cout<<endl;*/
memset(minn,0x3f3f3f,sizeof(minn));
memset(xiao,0x3f3f3f,sizeof(xiao));
for (int i=1;i<=n;i++)
{
maxx[belong[i]]=max(maxx[belong[i]],a[i]);
minn[belong[i]]=min(minn[belong[i]],a[i]);
// cout<<belong[i]<<' '<<maxx[belong[i]]<<' '<<minn[belong[i]]<<endl;
}
xiao[belong[1]]=minn[belong[1]];
//cout<<endl;
for (int i=1;i<=n;i++)
{
for (int j=head[i];j;j=e[j].next)
{
if (belong[i]!=belong[e[j].end])
new_add(belong[i],belong[e[j].end]),rd[belong[e[j].end]]++;
}
}
ed=belong[n];
tp_sort();
// for (int i=1;i<=color;i++)
// for (int j=new_head[i];j;j=new_e[j].next)
// cout<<i<<' '<<new_e[j].end<<endl;
// cout<<endl;
// for (int i=1;i<=n;i++)
// cout<<belong[i]<<' ';
// cout<<endl;
// cout<<'?'<<ed<<endl;
// cout<<endl;
dp();
cout<<f[ed];
return 0;
}
谨以此纪念我令人窒息的鬼畜操作
(碎碎念,很久没有自己想出一道蓝题的正解然后调出来了呢,果然是,对ac上瘾啊)
以上,退役前的碎碎念,感谢
不要留遗憾啊
版权声明:本文为weiya040214原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。