图论 tarjan缩点+最短路 的一道题

  • tarjan求强连通分量(为以后缩点打下良好的基础)

(如果不会tarjan的请点击这儿)

你需要的东西:
(1)、dfn[],表示这个点在dfs时是第几个被搜到的。
(2)、low[],表示这个点以及其子孙节点连的所有点中dfn最小的值
(3)、stack[],表示当前所有可能能构成是强连通分量的点。
(4)、vis[],表示一个点是否在stack中。
(5)、color[],记录每一个点强连通分量的编号。
(6)、deep,记录dfs树的深度
inline void tarjan(int now)
{
dfn[now]=++deep;
low[now]=deep;
vis[now]=1;
st.push(now);
for(int i=0;i<ver[now].size();i++)
{
int x=ver[now][i];
if(!dfn[x])
{
tarjan(x);
low[now]=min(low[now],low[x]);
}
else
{
if(vis[x])
low[now]=min(low[now],low[x]);
}
}
if(dfn[now]==low[now])
{
color[now]=++sum;
vis[now]=0;
while(st.top()!=now)
{
color[st.top()]=sum;
vis[st.top()]=0;
st.pop();
}
st.pop();
}
}
  • 缩点(去除图中的环)
//重点:这里建新图是依托强连通分量的编号来建的
for(int i=1;i<=n;i++)
{
for(int j=0;j<ver[i].size();j++)
{
int x=ver[i][j];
if(color[i]!=color[x])//如果不是属于同一个强连通分量中,那么就合并
{
g[color[i]].push_back(color[x]);
//千万不能写成g[i].push_back(x);坑死我了
}
}
}
//这一部分代码还可以适当优化...(想一想)
  • 对于点权与酒馆的一些处理(方便求最短路)
for(int i=1;i<=n;i++)
{
ww[color[i]]+=w[i];//将这个强连通分量中所有的点权全部加起来
if(tf[i])tf[color[i]]=1;//只要这个强连通分量中有一个结点有酒馆,那么就设定为有酒馆
}
  • 求最短路模板(然而实际是最长路)
//模板不做解释
inline void spfa()
{
d[color[s]]=ww[color[s]];
queue<int>q;
q.push(color[s]);
while(q.size())
{
int now=q.front();
q.pop();
for(int i=0;i<g[now].size();i++)
{
int x=g[now][i];
if(d[now]+ww[x]>d[x])
{
d[x]=d[now]+ww[x];
q.push(x);
}
}
}
}

所以...

在所有有酒馆的节点中选一个最大值输出就好了

for(int i=1;i<=sum;i++)
{
//cout<<d[i]<<" ";
if(tf[i])ans=max(ans,d[i]);
}

完整代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN=500000+10;
int n,m;
vector<int>ver[MAXN];
vector<int>g[MAXN];
int w[MAXN],ww[MAXN];
bool tf[MAXN];
int s,p,ans=0;
int dfn[MAXN],color[MAXN],low[MAXN];
int deep,sum;
bool vis[MAXN];
int d[MAXN];
stack<int>st;
inline int read()
{
int tot=0;
char c=getchar();
while(c<'0'||c>'9')
c=getchar();
while(c>='0'&&c<='9')
{
tot=tot*10+c-'0';
c=getchar();
}
return tot;
}
inline void tarjan(int now)
{
dfn[now]=++deep;
low[now]=deep;
vis[now]=1;
st.push(now);
for(int i=0;i<ver[now].size();i++)
{
int x=ver[now][i];
if(!dfn[x])
{
tarjan(x);
low[now]=min(low[now],low[x]);
}
else
{
if(vis[x])
low[now]=min(low[now],low[x]);
}
}
if(dfn[now]==low[now])
{
color[now]=++sum;
vis[now]=0;
while(st.top()!=now)
{
color[st.top()]=sum;
vis[st.top()]=0;
st.pop();
}
st.pop();
}
}
inline void spfa()
{
d[color[s]]=ww[color[s]];
queue<int>q;
q.push(color[s]);
while(q.size())
{
int now=q.front();
q.pop();
for(int i=0;i<g[now].size();i++)
{
int x=g[now][i];
if(d[now]+ww[x]>d[x])
{
d[x]=d[now]+ww[x];
q.push(x);
}
}
}
}
int main()
{
//freopen("testdata.in","r",stdin);
n=read();m=read();
for(int i=1;i<=m;i++)
{
int x=read(),y=read();
ver[x].push_back(y);
}
for(int i=1;i<=n;i++)
w[i]=read();
s=read();p=read();
for(int i=1;i<=p;i++)
{
int x=read();
tf[x]=1;
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
tarjan(i);
}
/*cout<<endl;
for(int i=1;i<=n;i++)
cout<<color[i]<<" ";
cout<<endl;*/
for(int i=1;i<=n;i++)
{
for(int j=0;j<ver[i].size();j++)
{
int x=ver[i][j];
if(color[i]!=color[x])
{
//cout<<i<<" "<<x<<" "<<color[i]<<" "<<color[x]<<endl;
g[color[i]].push_back(color[x]);
}
}
}
for(int i=1;i<=n;i++)
{
ww[color[i]]+=w[i];
if(tf[i])tf[color[i]]=1;
}
/*cout<<color[s]<<endl;
cout<<endl;
for(int i=1;i<=sum;i++)
{
for(int j=0;j<g[i].size();j++)cout<<i<<" "<<g[i][j]<<"\n";
}
cout<<endl;
for(int i=1;i<=sum;i++)
cout<<ww[i]<<" ";cout<<endl;
for(int i=1;i<=sum;i++)
cout<<tf[i]<<" ";cout<<endl;
cout<<ww[color[s]]<<endl;*/
spfa();
for(int i=1;i<=sum;i++)
{
//cout<<d[i]<<" ";
if(tf[i])ans=max(ans,d[i]);
}
//cout<<endl;
cout<<ans<<endl;
return 0;
}

洛谷 题解 P3627 【[APIO2009]抢掠计划】的更多相关文章

  1. P3627 [APIO2009]抢掠计划

    P3627 [APIO2009]抢掠计划 Tarjan缩点+最短(最长)路 显然的缩点...... 在缩点时,顺便维护每个强连通分量的总权值 缩完点按照惯例建个新图 然后跑一遍spfa最长路,枚举每个 ...

  2. 【题解】洛谷P3627 [APIO2009]抢掠计划(缩点+SPFA)

    洛谷P3627:https://www.luogu.org/problemnew/show/P3627 思路 由于有强连通分量 所以我们可以想到先把整个图缩点 缩点完之后再建一次图 把点权改为边权 并 ...

  3. 洛谷 P3627 [APIO2009]抢掠计划 题解

    Analysis 建图+强连通分量+SPFA求最长路 但要保证最后到达的点中包含酒馆 虽然思路并不难想,但要求的代码能力很高. #include<iostream> #include< ...

  4. 洛谷 P3627 [APIO2009]抢掠计划 Tarjan缩点+Spfa求最长路

    题目地址:https://www.luogu.com.cn/problem/P3627 第一次寒假训练的结测题,思路本身不难,但对于我这个码力蒟蒻来说实现难度不小-考试时肛了将近两个半小时才刚肛出来. ...

  5. [洛谷P3627][APIO2009]抢掠计划

    题目大意:给你一张$n(n\leqslant5\times10^5)$个点$m(m\leqslant5\times10^5)$条边的有向图,有点权,给你起点和一些可能的终点.问从起点开始,到任意一个终 ...

  6. 洛谷 P3627 [APIO2009]抢掠计划

    这题一看就是缩点,但是缩完点怎么办呢?首先我们把所有的包含酒吧的缩点找出来,打上标记,然后建立一张新图, 每个缩点上的点权就是他所包含的所有点的点权和.但是建图的时候要注意,每一对缩点之间可能有多条边 ...

  7. 【luogu P3627 [APIO2009]抢掠计划】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3627 把点权转化到边权上去. #include <stack> #include <que ...

  8. 题解 P3627 【[APIO2009]抢掠计划】

    咕了四个小时整整一晚上 P3627 [APIO2009] 抢掠计划(https://www.luogu.org/problemnew/show/P3627) 不难看出答案即为该有向图的最长链长度(允许 ...

  9. APIO2009 抢掠计划 Tarjan DAG-DP

    APIO2009 抢掠计划 Tarjan spfa/DAG-DP 题面 一道\(Tarjan\)缩点水题.因为可以反复经过节点,所以把一个联通快中的所有路口看做一个整体,缩点后直接跑\(spfa\)或 ...

随机推荐

  1. asp.net文件夹上传源码

    ASP.NET上传文件用FileUpLoad就可以,但是对文件夹的操作却不能用FileUpLoad来实现. 下面这个示例便是使用ASP.NET来实现上传文件夹并对文件夹进行压缩以及解压. ASP.NE ...

  2. NetworkX系列教程(10)-算法之二:最小/大生成树问题

    小书匠 Graph 图论  重头戏部分来了,写到这里我感觉得仔细认真点了,可能在NetworkX中,实现某些算法就一句话的事,但是这个算法是做什么的,用在什么地方,原理是怎么样的,不清除,所以,我决定 ...

  3. python3 pyinstaller 图标改变不了的问题

    命令 pyinstaller -F ./test.py --noconsole --icon=test.ico 在使用后可能发现新生成的图标仍然为默认图标,有以下解决方案: 将生成的exe文件复制到另 ...

  4. (转)centos7安装telnet服务

    借鉴:https://www.cnblogs.com/daipenglin/p/4934572.html 阅读目录 1 CentOS7.0 telnet-server 启动的问题 场景:在进行Teln ...

  5. JS中的常用的代码操作

    本文件介绍常用的js代码的DOM操作.CSS操作.对象(Object对象.Array对象.Number对象.String对象.Math对象.JSON对象和Console对象)操作说明. 一.DOM树的 ...

  6. arcgis 地理坐标系 699个,投影坐标系是4767

    import arcpy # Get the list of spatial references and print it. srs = arcpy.ListSpatialReferences(sp ...

  7. [Java]某日期时间加上若干分钟得到新的日期时间

    使用Java自带类库实现日期时间增减还是比自己人工拆分编写要牢靠,代码也简洁多了. 下面代码实现了在原有日期时间上加上一些分钟得到新的日期时间的功能,稍加改造还可以实现逆向运算. 代码: packag ...

  8. 连接池设置导致的“血案” 原创: 一页破书 一页破书 5月6日 这个问题被投诉的几个月了,一直没重视——内部客户嘛😿 问题现象: 隔几周就会出现 A服务调用B服务超时 脚趾头想就是防火墙的问题,A、B两服务之间有防火墙 找运维查看防火墙日志确实断掉了tcp连接,但是是因为B服务5分钟没有回包,下面这个表情就是我当时的心情——其实我们在防火墙、A服务、B服务都抓包了,几十个G的t

    连接池设置导致的“血案” 原创: 一页破书 一页破书 5月6日 这个问题被投诉的几个月了,一直没重视——内部客户嘛

  9. SSM配置基于注解AOP

    pom.xml <dependency> <groupId>org.springframework</groupId> <artifactId>spri ...

  10. ElasticSearch——数据建模最佳实践

    如何建模 mapping 设计非常重要,需要从两个维度进行考虑: 功能:搜索.排序.聚合 性能:存储的开锁.内存的开销.搜索的性能 mapping 注意事项: 加入新字段很容易(必要时需要 updat ...