2021.8.9提高B组模拟1T2 QYQ在艾泽拉斯(Tarjan强连通分量)(并查集)
Posted SSL_LKJ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021.8.9提高B组模拟1T2 QYQ在艾泽拉斯(Tarjan强连通分量)(并查集)相关的知识,希望对你有一定的参考价值。
QYQ在艾泽拉斯
题目大意
输入样例
3 2
1 2
3 1
1 2 1
0
输出样例
4
样例说明:
QYQ从3号点开始,走到2号点,最后走到1号点,结束旅程,共获得1+2+1=4价值的宝物
题目数据
解题思路
先用Tarjan强连通分量缩点
再用并查集求出每个岛屿最大的价值
我太蒟了,以至于不会敲这题的 dfs ,改了太久都没 AC ,只能用并查集,望各位大佬见谅
AC代码
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
int n,m,k,T,TT,tot,tot1,top,answer;
int f[100005],fa[100005],ru[100005],ans[100005],dfn[100005],low[100005],col[100005],sum[100005],num[100005],stak[100005],head[100005],head1[100005];
struct node
int to,next;
a[2000005],b[2000005];
void add(int x,int y)
a[++tot]=(node)y,head[x];
head[x]=tot;
void add1(int x,int y)
b[++tot1]=(node)y,head1[x];
head1[x]=tot1;
void Tarjan(int x)//模板
dfn[x]=low[x]=++T;
stak[++top]=x;
for(int i=head[x];i;i=a[i].next)
int v=a[i].to;
if(!dfn[v])
Tarjan(v);
low[x]=min(low[x],low[v]);
else if(!col[v])low[x]=min(low[x],low[v]);
if(dfn[x]==low[x])
col[x]=++TT;
sum[TT]+=num[x];
while(stak[top]!=x)sum[TT]+=num[stak[top]],col[stak[top--]]=TT;
top--;
return;
int getfather(int x)
if(fa[x]==x)return x;
return fa[x]=getfather(fa[x]);
void work(int x)
f[x]+=sum[x];
for(int i=head1[x];i;i=b[i].next)
getfather(x),getfather(b[i].to);
fa[fa[x]]=fa[b[i].to];
ru[b[i].to]--;
f[b[i].to]=max(f[x],f[b[i].to]);
if(!ru[b[i].to])work(b[i].to);
bool cmp(int x,int y)
return x>y;
int main()
freopen("azeroth.in","r",stdin);
freopen("azeroth.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
scanf("%d",&k);
for(int i=1;i<=n;i++)
if(!dfn[i])Tarjan(i);
for(int i=1;i<=n;i++)//建新图
for(int j=head[i];j;j=a[j].next)
int v=a[j].to;
if(col[i]!=col[v])
add1(col[i],col[v]);
ru[col[v]]++;
for(int i=1;i<=TT;i++)fa[i]=i;//初值
for(int i=1;i<=TT;i++)if(!ru[i])work(i);//并查集
for(int i=1;i<=TT;i++)getfather(i),ans[fa[i]]=max(ans[fa[i]],f[i]);//ans为各个岛屿最大价值
sort(ans+1,ans+n+1,cmp);//排序
for(int i=1;i<=min(n,k+1);i++)//求答案
answer+=ans[i];
printf("%d",answer);
return 0;
谢谢
以上是关于2021.8.9提高B组模拟1T2 QYQ在艾泽拉斯(Tarjan强连通分量)(并查集)的主要内容,如果未能解决你的问题,请参考以下文章