题目链接:

https://www.luogu.org/problem/P3387

一:ac思路

参考博客:

https://www.luogu.org/blog/wyz598085788/solution-p3387

思路:

1:在用tarjan缩点时,用num[cnt]记录每一个强连通分量的值

2:核心思路:虚拟头节点f和虚拟尾节点t

3:就是经过tarjan缩点之后,把每一个强连通分量看作一个节点建图,然后把每一个强连通分量的负值当作该边的权值

4:以f为起点,t为终点跑spfa

5:用虚拟头节点f和每一个节点建一条边,权值为-num[i],每一个节点和虚拟尾节点建一条边,权值为0

 int f=0;int t=cnt+1;for(int i=1;i<=cnt;i++){mapp[f].push_back(make_pair(i,-num[i]));mapp[i].push_back(make_pair(t,0));}
#include <bits/stdc++.h>using namespace std;
const int maxn=1e4+1;
vector<int>e[maxn];
set<int>ee[maxn];
int dfn[maxn],low[maxn],ins[maxn],color[maxn],timing,cnt,n,m,id[maxn];
int num[maxn],point[maxn];
stack<int>s;
vector<pair<int,int> >mapp[maxn];
int d[maxn],ing[maxn];void tarjan(int x)
{low[x]=dfn[x]=++timing;s.push(x);ins[x]=1;for(int i=0;i<e[x].size();i++){int v=e[x][i];if(!dfn[v]){tarjan(v);low[x]=min(low[x],low[v]);}else if(ins[v]){low[x]=min(low[x],dfn[v]);}}if(dfn[x]==low[x]){cnt++;while(s.top()!=x){color[s.top()]=cnt;ins[s.top()]=0;num[cnt]+= point[s.top()];s.pop();}color[s.top()]=cnt;ins[s.top()]=0;num[cnt]+=point[s.top()];s.pop();}
}void init()
{for(int i=1;i<=cnt;i++){ing[i]=0;d[i]=1e9;}
}int spfa(int x,int t)
{queue<int>q;q.push(x);d[x]=0;ing[x]=1;while(!q.empty()){int now=q.front();q.pop();ing[now]=0;for(int i=0;i<mapp[now].size();i++){int v=mapp[now][i].first;if(d[v]>d[now]+mapp[now][i].second){d[v]=d[now]+mapp[now][i].second;if(ing[v])continue;q.push(v);ing[v]=1;}}}return -d[t];
}int main()
{ios::sync_with_stdio(0);cin>>n>>m;for(int i=1;i<=n;i++){int x;cin>>x;point[i]=x;}for(int i=1;i<=m;i++){int a,b;cin>>a>>b;e[a].push_back(b);}for(int i=1;i<=n;i++){if(!dfn[i])tarjan(i);}for(int i=1;i<=n;i++){for(int j=0;j<e[i].size();j++){if(color[i]!=color[e[i][j]]&&ee[color[i]].find(color[e[i][j]])==ee[color[i]].end()){ee[color[i]].insert(color[e[i][j]]);id[color[e[i][j]]]++;mapp[color[i]].push_back(make_pair(color[e[i][j]],-num[color[e[i][j]]]));}}}int f=0;int t=cnt+1;for(int i=1;i<=cnt;i++){mapp[f].push_back(make_pair(i,-num[i]));mapp[i].push_back(make_pair(t,0));}init();cout<<spfa(f,t)<<endl;return 0;
}

二:让自己纠结多日的90分,9个测试点ac一个wa的代码

错因:

1:没有正确处理从哪一个节点开始spfa,到哪一个点的最长路径

2:一开始处理为spfa的起点为入度为零的节点,到出度为零的节点,的最长路径,然后从中取最大值

#include <bits/stdc++.h>using namespace std;
const int maxn=1e4+1;
vector<int>e[maxn];
set<int>ee[maxn];
int dfn[maxn],low[maxn],ins[maxn],color[maxn],timing,cnt,n,m,id[maxn];
int num[maxn],point[maxn];
stack<int>s;
vector<pair<int,int> >mapp[maxn];
int d[maxn],ing[maxn];void tarjan(int x)
{low[x]=dfn[x]=++timing;s.push(x);ins[x]=1;for(int i=0;i<e[x].size();i++){int v=e[x][i];if(!dfn[v]){tarjan(v);low[x]=min(low[x],low[v]);}else if(ins[v]){low[x]=min(low[x],dfn[v]);}}if(dfn[x]==low[x]){cnt++;while(s.top()!=x){color[s.top()]=cnt;ins[s.top()]=0;num[cnt]+= point[s.top()];s.pop();}color[s.top()]=cnt;ins[s.top()]=0;num[cnt]+=point[s.top()];s.pop();}
}void init()
{for(int i=1;i<=cnt;i++){ing[i]=0;d[i]=1e9;}
}int spfa(int x)
{queue<int>q;q.push(x);d[x]=0;ing[x]=1;while(!q.empty()){int now=q.front();q.pop();ing[now]=0;for(int i=0;i<mapp[now].size();i++){int v=mapp[now][i].first;if(d[v]>d[now]+mapp[now][i].second){d[v]=d[now]+mapp[now][i].second;if(ing[v])continue;q.push(v);ing[v]=1;}}}int mi=1e9;for(int i=1;i<=cnt;i++){if(ee[i].size()==0){mi=min(d[i],mi);}}return -mi;
}int main()
{ios::sync_with_stdio(0);cin>>n>>m;for(int i=1;i<=n;i++){int x;cin>>x;point[i]=x;}for(int i=1;i<=m;i++){int a,b;cin>>a>>b;e[a].push_back(b);}for(int i=1;i<=n;i++){if(!dfn[i])tarjan(i);}for(int i=1;i<=n;i++){for(int j=0;j<e[i].size();j++){if(color[i]!=color[e[i][j]]&&ee[color[i]].find(color[e[i][j]])==ee[color[i]].end()){ee[color[i]].insert(color[e[i][j]]);id[color[e[i][j]]]++;mapp[color[i]].push_back(make_pair(color[e[i][j]],-num[color[e[i][j]]]));}}}init();int ma=0;for(int i=1;i<=cnt;i++){if(id[i]==0){ma=max(spfa(i)+num[i],ma);}}if(ma==0){for(int i=1;i<=cnt;i++){ma+=num[i];}cout<<ma<<endl;}else{cout<<ma<<endl;}return 0;
}

洛谷 P3387 【模板】缩点 tarjan 虚拟头节点和虚拟尾节点相关推荐

  1. 强连通分量:洛谷P3387 模板:缩点

    传送门 顾名思义,模板awa #include <cstdio> #include <cstring> #include <cmath> #include < ...

  2. 洛谷 P3387(缩点后+处理 )

    题目链接:https://www.luogu.com.cn/problem/P3387 分析: 我们需要找出一条点权最大的路径. 不限制点的个数,那么对于一个环上的点被选择了,一整条环都应该被选择. ...

  3. 洛谷3387 模板 缩点

    题目:缩点 思路:tarjan缩点+最长路. 注意: 1.用dijkstra求最长路时,优先队列中的<运算符要反过来. 2.需要把所有入度为0的点为起点跑一遍最长路. 3.每次求最长路时,dis ...

  4. (Tarjan)洛谷P3387【模板】缩点

    洛谷P3387[模板]缩点 思路: 虽然是缩点模板题,但是明显感觉比同一个题单中的其他题都难. 题目思路已经提供给你:Tarjan缩点+DAGdp.就是用Tarjan缩点,重新建图之后,边拓扑排序边建 ...

  5. 洛谷 2921 记忆化搜索 tarjan 基环外向树

    洛谷 2921 记忆化搜索 tarjan 传送门 (https://www.luogu.org/problem/show?pid=2921) 做这题的经历有点玄学,,起因是某个random题的同学突然 ...

  6. 专题·树链剖分【including 洛谷·【模板】树链剖分

    初见安~~~终于学会了树剖~~~ [兴奋]当初机房的大佬在学树剖的时候我反复强调过:"学树剖没有前途的!!!" 恩.真香. 一.重链与重儿子 所谓树剖--树链剖分,就是赋予一个链的 ...

  7. 洛谷·【模板】点分树 | 震波【including 点分树

    初见安-这里是传送门:洛谷P6329 [模板]点分树 | 震波 一.点分树 其实你会点分治的话,点分树就是把点分治时的重心提出来重新连城一棵树. 比如当前点是u,求出子树v的重心root后将root与 ...

  8. 洛谷 P3469 [POI2008]BLO-Blockade (Tarjan,割点)

    P3469 [POI2008]BLO-Blockade https://www.luogu.org/problem/P3469 题目描述 There are exactly nn towns in B ...

  9. 洛谷P3387 【模板】缩点(tarjan)

    题目链接:https://www.luogu.org/problemnew/show/P3387 题目大意: 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只 ...

最新文章

  1. R语言grep函数和grepl函数字符匹配实战
  2. 解决MySQL自动断开连接的问题
  3. 快速生成树(RSTP)和传统生成树(STP)的区别(华为数通HCIE认证面试真题)...
  4. 优美的Fibonacci数列与矩阵
  5. [短彩信]C#短彩信模块开发设计(2)——配置
  6. 聊聊Spring Cloud版本的那些事儿
  7. 知云文献翻译打不开_比有道更好用的英文文献阅读翻译神器免费啦
  8. python——zip()、map()、enumerate()、filter()、apply函数
  9. 算法笔记_面试题_12.二叉搜索树的最近公共祖先
  10. 远控免杀专题(10)-TheFatRat免杀(VT免杀率22/70)
  11. cad打开a3样板图形_cad开始怎样设置A3纸?
  12. 企业微信SDK接口api调用代码
  13. mescroll报错
  14. 《FMEA潜在失效模式及效应分析实务》课程大纲--台湾李文棕老师
  15. 钱钟书论“反者道之动”
  16. Vue 中使用Pug
  17. python append 字典_Python3中使用append添加字典元素出现问题
  18. 笔记本电脑属于下列哪一类型的计算机,除尘清灰成本相差百倍!你的笔记本属于哪一类?...
  19. 谷歌的人工智能三大布局
  20. 如何在旧的iPhone或iPad上安装旧版本的iOS应用

热门文章

  1. lstm 文本分类_带有lstm和单词嵌入的灾难推文上的文本分类
  2. 如何在JavaScript中直观地设计状态
  3. lazada各国家站点讲解
  4. 【JS】json导出到excel,自定义文件名和后缀名
  5. Ubuntu20.04下面使用pycharm时候无法输入汉语的问题
  6. IDEA 程序包不存在,找不到符号但是明明存在对应的jar包 的解决方案
  7. 如何使用计算机做海报,用word做的海报步骤_word怎么设计海报
  8. English Learning - Day3 作业打卡 2022.12.9 周五
  9. [leetcode]Unique Paths II
  10. win10提示无法通过电话激活怎么办?