P4742 【[Wind Festival]Running In The Sky】

相信来做这道题的人肯定都学过 T a r j a n Tarjan Tarjan缩点吧,如果没有建议先去做P3387 【模板】缩点,如果你忘了,建议也去看看

满足上面要求后,你会惊奇发现,这两道题基本一样,唯一的差别就是这道题需要记录最大点权,比模板题多一个要求

但其实这很好想,在缩点的时候,我们另开一个数组记录每一个缩点之后的最值,其余部分完全一样。至于程序我就不贴了

然后就是跑最大值,其实就是跑最长路,我们可以使用拓扑,记忆化搜索或者DP,但是之前做的时候用的是拓扑,这里就只说拓扑的做法

我们用 d i s dis dis表示到达该点时的最长路, m a x n maxn maxn表示到达该点的最长路上的最大点权

在拓扑跑最长路的过程中,每更新一次最长路,就意味着这条最长路发生了改变,所以这个时候我们应当把 m a x n maxn maxn清空,重新更新一次最大点权,不然就会出错,在最后更新答案时,也要注意这个地方

#include <bits/stdc++.h>
using namespace std;
int n,m,ti,cnt,top,tot,ans=-99999999,sum,a[5000010],q[5000010],in[5000010],dis[5000010],pre[5000010],poi[5000010];
int dfn[5000010],low[5000010],vis[5000010],num[5000010],fir[5000010],head[5000010],heads[5000010],maxn[5000010];
int x[5000010],y[5000010];

struct node {
	int to,net;
} e[5000010],es[5000010];

void add(int u,int v) {
	e[++tot].to=v;
	e[tot].net=head[u];
	head[u]=tot;
}

void adds(int u,int v) {
	es[++tot].to=v;
	es[tot].net=heads[u];
	heads[u]=tot;
}

void tarjan(int x) {
	vis[x]=1;
	q[++top]=x;
	dfn[x]=low[x]=++ti;
	for(int i=head[x];i;i=e[i].net) {
		int v=e[i].to;
		if(!dfn[v]) {
			tarjan(v);
			low[x]=min(low[x],low[v]);
		}
		else {
			if(vis[v]) low[x]=min(low[x],dfn[v]);
		}
	}
	if(low[x]==dfn[x]) {
		++cnt;
		while(q[top+1]!=x) {
			vis[q[top]]=0;
			fir[q[top]]=cnt;
			num[cnt]+=a[q[top]];
			poi[cnt]=max(poi[cnt],a[q[top]]); //记录缩完点之后的最大点权 
			top--;
		}
	}
}

inline void topo() {
	queue<int> q;
	for(register int i=1;i<=cnt;i++) {
		dis[i]=num[i];
		maxn[i]=poi[i];
		if(!in[i]) q.push(i);
	} //记得初始化 
	while(!q.empty()) {
		int xx=q.front();
		q.pop();
		for(register int i=heads[xx];i;i=es[i].net) {
			int v=es[i].to;
			if(dis[xx]+num[v]>dis[v]) { //更新最大边权之和
				maxn[v]=0;             //记得清空,因为更换了路径 
				maxn[v]=max(poi[v],maxn[xx]);
				dis[v]=dis[xx]+num[v];
			}else if(dis[xx]+num[v]==dis[v]){
				maxn[v]=max(maxn[v],maxn[xx]);
			}//注意判断边权相同的情况,此时点权可能更大 
			if(--in[v]==0) q.push(v);
		}
	}
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=m;i++) {
		scanf("%d%d",&x[i],&y[i]);
		add(x[i],y[i]);
	}
	for(int i=1;i<=n;i++) {
		if(!dfn[i]) tarjan(i);
	}
	tot=0;
	for(int i=1;i<=m;i++) {
		if(fir[x[i]]!=fir[y[i]]){
			adds(fir[x[i]],fir[y[i]]);
			++in[fir[y[i]]];
		}
	}
	topo();
	for(int i=1;i<=cnt;i++) {
		if(ans<dis[i]) {
			ans=dis[i];
			sum=0;  //这个地方我最开始一直没考虑到(但是边权我却改了),95分调了很久 
			sum=max(sum,maxn[i]);
		}else if(ans==dis[i]){
			ans=dis[i];
			sum=max(sum,maxn[i]);
		}//和上面topo一样的思路 
	}
	printf("%d %d",ans,sum);
	return 0;
}
As an AI language model, I do not have access to future information or predict future events. However, some industries that are expected to see growth in the next decade based on current trends and projections include: 1. Technology: With the increasing reliance on technology and digital platforms, the technology industry is expected to see significant growth in areas such as artificial intelligence, cybersecurity, blockchain, and cloud computing. 2. Healthcare: The aging population and rising healthcare costs are likely to drive growth in healthcare industries such as telemedicine, personalized medicine, and healthcare robotics. 3. Renewable Energy: As the world continues to move towards a more sustainable future, the renewable energy industry is expected to see significant growth in areas such as solar, wind, and geothermal power. 4. E-commerce: The rise of online shopping and the increasing adoption of mobile devices are likely to drive growth in the e-commerce industry, with the potential for new innovations in areas such as augmented reality and voice-enabled shopping. 5. Biotechnology: Advances in biotechnology are likely to drive growth in areas such as gene editing, regenerative medicine, and precision medicine. 6. Education: The increasing demand for lifelong learning and workforce development is likely to drive growth in the online education and training industry. 7. Finance: The adoption of new technologies such as blockchain and artificial intelligence is likely to drive growth and innovation in the finance industry, particularly in areas such as fintech and digital banking.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值