Description

在艾泽拉斯的无尽之海里,有着一群不为人知的由各个种族的冒险者统治的岛屿,这些岛屿都很庞大,足以在上面建造许多的城市,城市之间有一些单向道路连接。
有一天,QYQ无意中发现了这些岛屿,并且发现在每个城市的地下都或多或少埋藏着一些装备、金币、宝物……
可是正当QYQ兴奋不已打算全部把它们拿走时,他却惊奇的发现你的魔法在这里被限制住了,唯一可用的技能就是闪现,而且魔法只够他使用K次这个技能了,每次使用这个技能QYQ只能从一个岛屿上闪现到另外一个岛屿上。每一个岛屿只能登上一次,QYQ可以从任何一个城市开始旅程,在任何一个城市结束旅程。
城市的数量共有n个,有m条道路,每一条道路有两个参数u,v,表示从u到v有一条道路,但你只能由u到v走,两个城市属于相同的岛屿当且仅当暂时将所有道路视为双向道路时可以从其中一个城市走到另一个城市(可以途径其它城市)。
每一个城市都有一个宝物的总价值v[i],你的任务是帮助QYQ得到最大总价值的宝物,并输出这个值。

Input

从文件azeroth.in中输入数据。
输入的第一行包含两个整数n,m
输入的第二行到第m+1行,每行包含2个整数u,v,代表你可以从城市u走到城市v
输入的第m+2行包含n个整数,第i个整数代表v[i],即这个城市的宝物总价值。
输入的第m+3行包含一个整数K,代表你可以使用技能的次数。

Output

输出到文件azeroth.out中。
输出的第一行包含一个整数,代表QYQ能获得的最大的宝物总价值

Sample Input

3 2
1 2
3 1
1 2 1
0

Sample Output

4
样例说明:
QYQ从3号点开始,走到2号点,最后走到1号点,结束旅程,共获得1+2+1=4价值的宝物

Data Constraint

对于30%的数据:n<=10,K=0
对于50%的数据:n<=100,m<=100,K<=1
对于100%的数据:1<=n<=100000,1<=m<=1000000,1<=v[i]<=1000,0<=K<=100000
图中可能会有重边、自环。

思路

题目大意是给你一个有向图,选择k+1个能获取最大价值的联通块的价值总和

显然tarjan缩点+topsortDP就可以解决啦!

代码要打得优美一点,不然就会T飞

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
const int maxn=1e5+77,maxm=1e6+77;
int list[maxn],V[maxn],VV[maxn],x[maxm],y[maxm],low[maxn],dfn[maxn],f[maxn],fa[maxn],dp[maxn],ans[maxn],d[maxn],size[maxn],n,m,k,ass,cnt,tot,scr;
bool instack[maxn],vis[maxn];
stack<int> s;
struct E
{int to,next;
}e[maxm];
int gf(int x)
{return x==fa[x]?x:fa[x]=gf(fa[x]);
}
void add(int u,int v)
{e[++cnt].to=v; e[cnt].next=list[u]; list[u]=cnt;
}
void tarjan(int u)
{ dfn[u]=low[u]=++tot;s.push(u); instack[u]=1; vis[u]=1;for(int i=list[u]; i; i=e[i].next){int v=e[i].to;if(!vis[v]){tarjan(v); low[u]=min(low[u],low[v]);}else if(instack[v])low[u]=min(low[u],dfn[v]);}if(dfn[u]==low[u]){scr++;int t=s.top(); s.pop(); instack[t]=0; f[t]=scr; V[scr]+=VV[t];while(u!=t){t=s.top(); s.pop(); instack[t]=0; f[t]=scr; V[scr]+=VV[t];}}
}
int solve()
{queue<int> q;for(int i=1; i<=scr; i++)if(d[i]==0) q.push(i);int ss=0;while(!q.empty()){int u=q.front(); q.pop(); dp[u]+=V[u]; int t=gf(u); ans[t]=max(ans[t],dp[u]);for(int i=list[u]; i; i=e[i].next){int v=e[i].to;d[v]--; dp[v]=max(dp[u],dp[v]);if(!d[v]) q.push(v);}}
}
int main()
{freopen("azeroth.in","r",stdin); freopen("azeroth.out","w",stdout);scanf("%d%d",&n,&m);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++) scanf("%d",&VV[i]);for(int i=1; i<=n; i++) if(!vis[i]) tarjan(i);memset(list,0,sizeof(list)); memset(e,0,sizeof(e)); cnt=0;for(int i=1; i<=scr; i++) fa[i]=i,size[i]=1;for(int i=1; i<=m; i++) if(f[x[i]]!=f[y[i]]){add(f[x[i]],f[y[i]]),d[f[y[i]]]++;int X=gf(f[x[i]]),Y=gf(f[y[i]]);if(X!=Y){if(size[X]>size[Y]) fa[Y]=X,size[X]+=size[Y];else fa[X]=Y,size[Y]+=size[X];}}memset(vis,0,sizeof(vis));
//  for(int i=1; i<=scr; i++) dp[i]=V[i];solve();sort(ans+1,ans+n+1);scanf("%d",&k);for(int i=n; i>=max(n-k,1); i--){ass+=ans[i];}printf("%d",ass);
}

【JZOJ A组】QYQ在艾泽拉斯相关推荐

  1. 2021.8.9【提高B组模拟1】T2 QYQ在艾泽拉斯(Tarjan强连通分量)(并查集)

    QYQ在艾泽拉斯 题目大意 输入样例 3 2 1 2 3 1 1 2 1 0 输出样例 4 样例说明: QYQ从3号点开始,走到2号点,最后走到1号点,结束旅程,共获得1+2+1=4价值的宝物 题目数 ...

  2. QYQ在艾泽拉斯(并查集)(Tarjan)(拓扑序DP)

    QYQ在艾泽拉斯 题目大意 给你一个有向图,然后定义一个区域是将有向边看做无向边所形成的连通块. 然后你可以选 K+1 个区域,从任意点出发走到任意点. 然后点有点权,要你最大化点权和. 思路 看到有 ...

  3. 【gmoj】 【tarjan】 【拓扑】 【并查集】 QYQ在艾泽拉斯

    [gmoj] [tarjan] [拓扑][并查集] QYQ在艾泽拉斯 题目 解题思路 因为可能出现环用tarjan缩点 再建一个新图 用按拓扑序跑一边DP 求出一个连通块中从哪个点跑出来的价值最大 k ...

  4. [Tarjan][并查集][dp] Jzoj P4253 QYQ在艾泽拉斯

    Description 在艾泽拉斯的无尽之海里,有着一群不为人知的由各个种族的冒险者统治的岛屿,这些岛屿都很庞大,足以在上面建造许多的城市,城市之间有一些单向道路连接. 有一天,QYQ无意中发现了这些 ...

  5. [拓扑排序][DP][Tarjan][并查集]JZOJ 4253 QYQ在艾泽拉斯

    Description 在艾泽拉斯的无尽之海里,有着一群不为人知的由各个种族的冒险者统治的岛屿,这些岛屿都很庞大,足以在上面建造许多的城市,城市之间有一些单向道路连接. 有一天,QYQ无意中发现了这些 ...

  6. Jzoj P4253 QYQ在艾泽拉斯___强连通分量缩点+拓扑序dp

    题目大意: Q Y Q QYQ QYQ有 K K K次技能,每次可以从一个岛屿上闪现到另外一个岛屿上,每一个岛屿只能登上一次. Q Y Q QYQ QYQ能从任何一个城市开始旅程,也能在任何一个城市结 ...

  7. 2021.08.09【NOIP提高B组】模拟 QYQ在艾泽拉斯

    思路: 直接缩点然后贪心走,注意细节 c o d e code code #include<iostream> #include<cstdio> #include<alg ...

  8. 【JZOJ4253】QYQ在艾泽拉斯

    description 在艾泽拉斯的无尽之海里,有着一群不为人知的由各个种族的冒险者统治的岛屿,这些岛屿都很庞大,足以在上面建造许多的城市,城市之间有一些单向道路连接. 有一天,QYQ无意中发现了这些 ...

  9. jzoj C组 2017.1.19 比赛

    第一题--小x的游戏 题目描述 Tac游戏在一个4*4的方格上进行.起先可能会在16个方格中出现一个标记'T',其余的方格是空着的.游戏有两个玩家,小x和小o.小x先开始,然后游戏轮流进行.每一步玩家 ...

最新文章

  1. ubuntu下安装 python 常用软件
  2. dubbo学习之-常用功能
  3. python3 redis操作 错误 cannot import name 'StrictRedis' from 'redis'
  4. 《转载》Python并发编程之线程池/进程池--concurrent.futures模块
  5. 警方办案滥用谷歌地理围栏,小伙三次骑车路过案发点被视作嫌犯
  6. Vue+Openlayers+HIKVSION实现点击摄像头进行预览
  7. Linux shell脚本中单双引号的区别
  8. codeblocks如何让输出结果 空格_简单讲讲如何实现两个正整数相加,然后输出这个结果...
  9. Aruba与中国电信国际有限公司达成战略合作 助力中国企业扬帆出海
  10. RabbitMQ的基本概念
  11. VB从程序中生成Exe文件
  12. 使用PHP来简单的创建一个RPC服务
  13. ValueError: Object arrays cannot be loaded when allow_pickle=False 报错解决
  14. NCBI引物设计-查找目的基因前后序列方法、序列比对
  15. otn与stn网络_mstp和stn的区别
  16. K8S学习之容器探测 livenessProbe、readinessProbe、startupProbe、lifecycle
  17. 电脑键盘上各个键的作用
  18. 10年程序员私单的经历,送你3个找客户的关键技巧
  19. VGA主机连接HDMI显示器
  20. 张小龙演讲PPT: APP产品经理必须要懂的30条原则

热门文章

  1. LintCode 92: Backpack (经典背包DP题)
  2. JavaScript 使用canvas压缩图片
  3. Selecting Windows SDK version
  4. 微信小程序日历加课表项目
  5. bootstrap修改样式表
  6. Dumpbin工具参数详解
  7. Linux扩大原有磁盘以增大LVM空间【扩容partion分区方式】
  8. Linux重定向符号和特殊符号
  9. java隋唐系列游戏下载,隋唐大业全面战争
  10. python连接redis集群如何释放内存_python 连接 redis cluster 集群