0分WA求助
查看原帖
0分WA求助
895690
gghack_Nythix楼主2024/1/6 17:31

rt

#include<bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
vector<int>g[400005],newg[400005];
int K[500005],n,m,pos[500005],maxblock[500005],sumblock[500005],dep,cur,dpmax[500005],dpsum[500005];
int dfn[500005],low[500005];
int deg[500005];
bool vis[500005];
stack<int>stk;
struct node{
	int u,v;
}edge[500005];
namespace gghack{
	void tarjan(int now){
		dfn[now] = low[now] = ++dep;
		stk.push(now);
		vis[now] = 1;
		for(auto x : g[now]){
			if(!dfn[x]){
				tarjan(x);
				low[now] = min(low[x],low[now]);//前向边 
			}
			else if(vis[x])low[now] = min(low[x],dfn[now]);//返祖边
			//横插边不在子树中,同时没有被标记,不用管 
		}
		if(dfn[now] == low[now]){
			++cur;
			while(stk.top()!=now){
				int noww = stk.top();
				stk.pop();
				vis[noww] = 0;
				maxblock[cur] = max(maxblock[cur],K[noww]);
				sumblock[cur] += K[noww];
				pos[noww] = cur;
			}
			stk.pop();
			vis[now] = 0;
			maxblock[cur] = max(maxblock[cur],K[now]);
			sumblock[cur] += K[now];
			pos[now] = cur;
		}
		return ;
	}
	void topo(){
		queue<int>q;
		for(int i = 1;i <= cur;++i){dpsum[i] = sumblock[i],dpmax[i] = maxblock[i];if(!deg[i])q.push(i);}
		while(!q.empty()){
			int now = q.front();
			q.pop();
			for(auto x : newg[now]){
				if(dpsum[now] + sumblock[x] > dpsum[x])dpmax[x] = 0,dpmax[x] = max(dpmax[now],maxblock[x]),dpsum[x] = dpsum[now] + sumblock[x];
				else if(dpsum[now] + sumblock[x] == dpsum[x])dpmax[x] = max(dpmax[now],dpmax[x]);
				deg[x]--;
				if(!deg[x])q.push(x);
			}
		}
		for(int i = 1;i <= cur;++i){
			if(dpsum[0] < dpsum[i]){
				dpsum[0] = dpsum[i];
				dpmax[0] = 0;
				dpmax[0] = maxblock[i];
			}
			else if(dpsum[0] == dpsum[i])dpmax[0] = max(maxblock[i],dpmax[0]);
		}
		cout << dpsum[0] << " " << dpmax[0] << '\n';
		return ;
	}
	void main(){
		ios::sync_with_stdio(false);
		cin.tie(0);
		cin >> n >> m;
		int u,v;
		for(int i = 1;i <= n;++i)cin >> K[i];
		for(int i = 1;i <= m;++i){
			cin >> u >> v;
			g[u].pb(v);
			edge[i].u = u,edge[i].v = v;
		}
		for(int i = 1;i <= n;++i)if(!dfn[i])tarjan(i);
		for(int i = 1;i <= m;++i){
			int ru = pos[edge[i].u],rv = pos[edge[i].v]; 
			if(ru == rv)continue;
			newg[ru].pb(rv);
			deg[rv]++;
		}
		topo();
		return ;
	}
}
signed main(){gghack::main();}
2024/1/6 17:31
加载中...