AtCoder Beginner Contest 188 E

  • 题意:有(n)个点,(m)条单向边,保证每条边的起点小于终点,每个点都有权值,找到联通的点的两个点的最大差值.
  • 题解:因为题目说了起点小于终点,所以我们可以反向存边,然后维护连通边的前缀最小值,如果当前点的入度不为(0),则更新答案.
  • 代码:
#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
#define rep(a,b,c) for(int a=b;a<=c;++a)
#define per(a,b,c) for(int a=b;a>=c;--a)
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}

int n,m;
vector<int> v[N];
int a[N];
int son_min[N];
int ans=-INF;

void dfs(int u){
	son_min[u]=INF;

	for(auto w:v[u]){  //from
		son_min[u]=min(son_min[u],son_min[w]);
	}

	if(!v[u].empty()) ans=max(ans,a[u]-son_min[u]);

	son_min[u]=min(son_min[u],a[u]);
}



int main() {
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

	cin>>n>>m;

	rep(i,1,n) cin>>a[i];

	rep(i,1,m){
		int x,y;
		cin>>x>>y;
		v[y].pb(x);
	}

	rep(i,1,n){
		dfs(i);
	}

	cout<<ans<<'
';


    return 0;
}

原文地址:https://www.cnblogs.com/lr599909928/p/14289160.html