tarjan缩点 + dp 10pts求调(悬关
查看原帖
tarjan缩点 + dp 10pts求调(悬关
1050431
DevilsFlame楼主2024/8/11 11:45
#include<bits/stdc++.h>
#define N 100010
using namespace std;
int dfn[N],low[N],stk[N],top,col,s[N],cnt,to[N],n,m;
int in[N];
struct Node
{
	int min,max,v;
}c[N];
vector <int> e[N],c_e[N];
int x,y,z;
inline void tarjan(int x)
{
	dfn[x] = low[x] = ++ cnt;
	in[x] = 1;
	stk[++ top] = x;
	for(int i = 0;i < e[x].size();i ++)
	{
		int v = e[x][i];
		if(!dfn[v])
		{
			tarjan(v);
			low[x] = min(low[x],low[v]);
		}
		else if(in[v]) low[x] = min(low[x],dfn[v]);
	}
	if(low[x] == dfn[x])
	{
		col ++;
		c[col].min = s[x];
		c[col].max = s[x];
		in[x] = 0;
		to[x] = col;
		while(stk[top] != x)
		{
			int y = stk[top];
			to[y] = col;
			in[y] = 0;
			c[col].min = min(c[col].min,s[y]);
			c[col].max = max(c[col].max,s[y]);
			top --;
		}
		top --;
	}
	return;
}
inline void dp(int x)
{
	for(int i = 0;i < c_e[x].size();i ++)
	{
		int v = c_e[x][i];
		in[v] --;
		c[v].min = min(c[x].min,c[v].min);
		c[v].v = max(max(c[x].v,c[v].v),c[v].max - c[v].min);
		if(!in[v]) dp(v);
	}
	return;
}
inline void build()
{
	map <int,map <int,bool> > pl;
	for(int i = 1;i <= n;i ++)
	{
		int u = to[i];
		for(int j = 0;j < e[x].size();j)
		{
			e[x].erase(e[x].begin());
			int v = to[e[x][j]];
			if(u == v || pl[u][v]) continue;
			pl[u][v] = 1;
			c_e[u].push_back(v);
			in[v] ++;
		}
	}
	return;
}
inline void read(int &x)
{
	x = 0;
	int f = 1;
	char s = getchar();
	while(s < '0' || s > '9')
	{
		if(s == '-') f = -1;
		s = getchar();
	}
	while(s >= '0' && s <= '9')
	{
		x = x * 10 + s - 48;
		s = getchar();
	}
	x *= f;
	return;
}
int main()
{
	read(n),read(m);
	for(int i = 1;i <= n;i ++) read(s[i]);
	for(int i = 1;i <= m;i ++)
	{
		read(x),read(y),read(z);
		e[x].push_back(y);
		if(z == 2) e[y].push_back(x);
	}
	tarjan(1);
	build();
	dp(to[1]);
	int v = to[n];
	if(c[v].v < 1)
	{
		printf("0\n");
		return 0;
	}
	printf("%d\n",c[v].v);
	return 0;
}
2024/8/11 11:45
加载中...