【BZOJ1179】atm,tarjan缩点+最长路径
2016-05-21 08:01
429 查看
Time:2016.05.21
Author:xiaoyimi
转载注明出处谢谢
传送门
思路:
题目中是一个带点权的有向图,如果这是一个没有环的图那么问题就很简单,拓扑或者直接求最长(短)路径什么的信手拈来,但是它有环,这就要求我们对图进行重构,把它搞成一个有向无环图,然后求得极值路径就可以了
tarjan缩点重构图,然后在重构图上跑最长(短)路,最后的答案就是max(dis[有酒吧的点])
注意:
1.还是要注意,重构图和原图不能搞混了……
2.如果跑最长路的话,dis不要初始化为0,可能出现起点周围的点权都是0,直接导致从起点搜索一遍,没有点入队的情况
代码:
Author:xiaoyimi
转载注明出处谢谢
传送门
思路:
题目中是一个带点权的有向图,如果这是一个没有环的图那么问题就很简单,拓扑或者直接求最长(短)路径什么的信手拈来,但是它有环,这就要求我们对图进行重构,把它搞成一个有向无环图,然后求得极值路径就可以了
tarjan缩点重构图,然后在重构图上跑最长(短)路,最后的答案就是max(dis[有酒吧的点])
注意:
1.还是要注意,重构图和原图不能搞混了……
2.如果跑最长路的话,dis不要初始化为0,可能出现起点周围的点权都是0,直接导致从起点搜索一遍,没有点入队的情况
代码:
#include<bits/stdc++.h> using namespace std; #define M 500005 int in() { int t=0;char ch=getchar(); while (!isdigit(ch)) ch=getchar(); while (isdigit(ch)) t=(t<<1)+(t<<3)+ch-48,ch=getchar(); return t; } int n=in(),m=in(),s,p,tot,cnt; struct edge{int u,v,next;}e[M],E[M]; int first[M],c[M],dfn[M],low[M],belong[M],First[M],C[M],dis[M]; bool is_end[M],vis[M]; stack<int>S; queue<int>Q; void add(int y,int x){e[++tot]=(edge){x,y,first[x]};first[x]=tot;} void Add(int x,int y){E[++tot]=(edge){x,y,First[x]};First[x]=tot;} void dfs(int x) { dfn[x]=low[x]=++cnt; S.push(x); vis[x]=1; for (int i=first[x];i;i=e[i].next) if (!dfn[e[i].v]) dfs(e[i].v), low[x]=min(low[x],low[e[i].v]); else if (vis[e[i].v]) low[x]=min(low[x],dfn[e[i].v]); if (dfn[x]==low[x]) { C[x]=0; for (int y=-1;y!=x;y=S.top(),S.pop()) belong[S.top()]=x, C[x]+=c[S.top()], vis[S.top()]=0; } } main() { for (int i=1;i<=m;i++) add(in(),in()); for (int i=1;i<=n;i++) c[i]=in(); s=in();p=in(); for (int i=1;i<=p;i++) is_end[in()]=1; tot=0; for (int i=1;i<=n;i++) if (!dfn[i]) dfs(i); for (int i=1;i<=n;i++) for (int j=first[i];j;j=e[j].next) if (belong[i]!=belong[e[j].v]) Add(belong[i],belong[e[j].v]); memset(dis,63,sizeof(dis)); Q.push(belong[s]);vis[belong[s]]=1; dis[belong[s]]=-C[belong[s]]; while (!Q.empty()) { int x=Q.front(); Q.pop(); vis[x]=0; for (int i=First[x];i;i=E[i].next) if (dis[x]-C[E[i].v]<dis[E[i].v]) { dis[E[i].v]=dis[x]-C[E[i].v]; if (!vis[E[i].v]) Q.push(E[i].v),vis[E[i].v]=1; } } int ans=0; for (int i=1;i<=n;i++) if (is_end[i]) ans=min(ans,dis[belong[i]]); printf("%d",-ans); }
相关文章推荐
- 智能一代云平台(六):移动开发之Ionic研究
- lua table remove元素的问题
- codeforces6D【dfs】
- 蓝牙OBEX剖析(二)-- 流程解析
- nrf51822学习之PPI裸板程序之对于定时器0计数方式的疑惑
- 关于VC6和VC9的区别
- cf9C. Hexadecimal's Numbers
- 基于Echarts的销售企业经营数据分析-产品组合
- LeetCode 59. Spiral Matrix II(螺旋矩阵)
- 设计模式学习笔记之命令模式
- 蓝牙OBEX剖析(一)
- 有很多东西还是有用的
- 修改weblogic jvm启动参数
- 函数接口
- LeetCode 58. Length of Last Word(最后一个单词的长度)
- 线程间协作的二种方式:wait,notify,notifyAll和condition
- LeetCode 57. Insert Interval(插入区间)
- js时间戳格式化成日期格式
- Playing with ptrace, Part I
- [Java]阶段性知识点、技术总结