m三个点,什么情况
查看原帖
m三个点,什么情况
126334
jr_tat楼主2020/10/9 20:31
#include <bits/stdc++.h>
using namespace std;
int dp[10001];//树的直径的一系列操作 
vector<int> ed[10001];
vector<int> ned[10001];//新树 
vector<int> scc[10001];
int nva[10001];//新权值 
int num=0;//scc的个数 
int f[10001];//节点所属的scc 
int va[10001]={0},vi[10001]={0},dfn[10001]={0},low[10001]={0};//value visit 
stack<int> ans;
int st[100001]={0};//是否在栈中 
void dfs(int x,int d){
	d++;//时间戳 
	vi[x]=1;//拜访过 
	low[x]=dfn[x]=d;
	if(!st[x]){//如果不在栈中则入栈 
		st[x]=1;
		ans.push(x);
	}
	for(int i=0;i<ed[x].size();i++){
		int to=ed[x][i];
		//cout<<to<<' '<<vi[to]<<endl;
		if(!vi[to]){
			dfs(to,d);
			low[x]=min(low[x],low[to]); 
		}
		else {
			if(st[to]==1){
				low[x]=min(low[x],dfn[to]);//更新lowbit 
			}
		}
	}
	if(low[x]==dfn[x]){
		num++;
		do{
			scc[num].push_back(ans.top());//放到ssc的数组中
			nva[num]+=va[ans.top()];//计算scc权值和 
			st[ans.top()]=0; //弹出 
			if(ans.top()==x){
				ans.pop();
				break;
			}
			ans.pop();
			
		}while(1); 
	}
}
void dfs2(int x){
	dp[x]=nva[x];
	for(int i=0;i<ned[x].size();i++){
		int to=ned[x][i];
		dfs2(to);
		dp[x]=max(dp[x],dp[to]+nva[x]);
	}
}
int main(int argc, char** argv) {
	int n,m;
	int e[100001]={0},t[100001]={0};
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>va[i];
	}
	for(int i=1;i<=m;i++){
		int a,b;
		cin>>a>>b;
		e[i]=a;
		t[i]=b;
		ed[a].push_back(b);//有向 
		//ed[b].push_back(a);
	}
	//初始化完成 
	for(int i=1;i<=n;i++){
		if(!vi[i]){//可能是森林 
			dfs(i,0);
		}
	} 
	//check
	for(int i=1;i<=num;i++){
		for(int j=0;j<scc[i].size();j++){
			f[scc[i][j]]=i;//每个节点属于的scc 
		} 
	}
	//
	int in[10001];//判断根节点 
	for(int i=1;i<=m;i++){
		if(f[e[i]]!=f[t[i]]){
			ned[f[e[i]]].push_back(f[t[i]]);//连成边 
			in[f[t[i]]]++;//入度+1 
		}
	} 
	//树的直径 
	vector <int>node;
	for(int i=1;i<=num;i++){
		if(in[i]==0)node.push_back(i);
	}
	int maxx;//最长边权 
	for(int i=0;i<node.size();i++){
	    dfs2(node[i]);
	    maxx=max(maxx,dp[node[i]]);
	} 
	cout<<maxx;
	return 0;
}
2020/10/9 20:31
加载中...