40pts求条 悬一关TAT
查看原帖
40pts求条 悬一关TAT
1063855
xu_zhihao楼主2024/7/29 13:44
#include<bits/stdc++.h>
using namespace std;
int dfn[100010];
int low[100010];
int sum[100010];
int k[100010];
int dp[100010];
int ru[100010];
stack<int>st;
vector<int>v[10010];
vector<int>p[10010];
int cnt;
int rt[100010];
void Tarjan(int u){
	dfn[u]=low[u]=++cnt;
    st.push(u);
    int l=v[u].size();
    for(int i=0;i<l;i++){
    	if(!dfn[v[u][i]]){
    		Tarjan(v[u][i]);
    		low[u]=min(low[u],low[v[u][i]]);
		}
		else if(!rt[v[u][i]]){
			low[u]=min(dfn[v[u][i]],low[u]);
		}
	}
	if(low[u]==dfn[u]){
		rt[u]=u;
		sum[u]+=k[u];
		while(st.top()!=u){
			rt[st.top()]=u;
			sum[u]+=k[st.top()];
			st.pop();
		}
		st.pop();
	}
}
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&k[i]);
	}
	for(int i=1;i<=m;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		v[l].push_back(r);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i]){
		    Tarjan(i);
	    }
	}
	for(int i=1;i<=n;i++){
		int l=v[i].size();
		for(int j=0;j<l;j++){
			if(rt[i]!=rt[v[i][j]]){
				p[rt[i]].push_back(rt[v[i][j]]);
				dp[rt[i]]=sum[rt[i]];
				dp[rt[v[i][j]]]=sum[rt[v[i][j]]];
				ru[rt[v[i][j]]]++;
			}
		}
	}
	int f=0;
	for(int i=2;i<=n;i++){
		if(rt[i]!=rt[1]){
			f=1;
			break;
		}
	}
	if(!f){
		cout<<sum[rt[1]]<<endl;
		return 0; 
	}
	for(int i=1;i<=n;i++){
		int id=0;
		for(int j=1;j<=n;j++)if(p[j].size()){
			if(!ru[j]){
				id=j;
				break;
			} 
		}
		if(!id){
			break;
		}
		int l=p[id].size();
		for(int j=0;j<l;j++){
			dp[p[id][j]]+=dp[id];
			ru[p[id][j]]--;
		}
		ru[id]=-1;
	}
	int mx=0;
	for(int i=1;i<=n;i++){
		mx=max(mx,dp[i]);
	}
	cout<<mx;
	return 0;
}
2024/7/29 13:44
加载中...