洛谷3387:【模板】缩点——题解
2018-04-02 19:51
141 查看
https://www.luogu.org/problemnew/show/P3387
给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。
允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。
有环我们很不好判断,但是显然在一个强连通分量里面的点我们都可以到达。
所以缩起来之后就是一个DAG,之后随便你怎么算都行(bfs/dfs)
(我觉得并不算是dp emmm)
#include<stack> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N=1e4+5; const int M=1e5+5; inline int read(){ int x=0,w=1;char ch=0; while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*w; } struct node{ int w,to,nxt; }e[2][M]; int cnt,h[2] ; inline void add(int u,int v,int k){ e[k][++cnt].to=v;e[k][cnt].nxt=h[k][u];h[k][u]=cnt; } int dfn ,low ,val ,to ,sum ,f ,indeg ,t,l; stack<int>q; queue<int>p; bool inq ,vis ; void tarjan(int u){ int v; dfn[u]=low[u]=++t; q.push(u);inq[u]=1; for(int i=h[0][u];i;i=e[0][i].nxt){ v=e[0][i].to; if(!dfn[v]){ tarjan(v); low[u]=min(low[u],low[v]); }else if(inq[v]){ low[u]=min(low[u],dfn[v]); } } if(dfn[u]==low[u]){ l++; do{ v=q.top(); q.pop(); inq[v]=0; to[v]=l; sum[l]+=val[v]; }while(v!=u); } } void bfs(int u){ vis[u]=1;f[u]=sum[u]; p.push(u); while(!p.empty()){ u=p.front();p.pop();vis[u]=0; for(int i=h[1][u];i;i=e[1][i].nxt){ int v=e[1][i].to; if(f[v]<f[u]+sum[v]){ f[v]=f[u]+sum[v]; if(!vis[v]){ vis[v]=1; p.push(v); } } } } } int main(){ int n=read(),m=read(); for(int i=1;i<=n;i++)val[i]=read(); for(int i=1;i<=m;i++){ int u=read(),v=read(); add(u,v,0); } for(int i=1;i<=n;i++){ if(!dfn[i])tarjan(i); } for(int u=1;u<=n;u++){ for(int j=h[0][u];j;j=e[0][j].nxt){ int v=to[e[0][j].to]; bool link=0; for(int k=h[1][to[u]];k&&!link;k=e[1][k].nxt){ int w=e[1][k].to; if(v==w)link=1; } if(!link&&to[u]!=v){ add(to[u],v,1); indeg[v]++; } } } memset(f,-127,sizeof(f)); for(int i=1;i<=l;i++){ if(!indeg[i]){ bfs(i); } } int ans=0; for(int i=1;i<=l;i++)ans=max(ans,f[i]); printf("%d\n",ans); return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
相关文章推荐
- 洛谷3387 模板 缩点
- P3387 【模板】缩点
- 连通分量模板:tarjan: 求割点 && 桥 && 缩点 && 强连通分量 && 双连通分量 && LCA(近期公共祖先)
- 图论--有向图强连通分量的标记及缩点模板
- tarjan - SPFA - Luogu 3387【模板】缩点
- Tarjan缩点【模板】
- 浅谈Tarjan缩点(分析+模板)
- 【模板】Tarjan缩点,强连通分量 洛谷P2341 [HAOI2006]受欢迎的牛 [2017年6月计划 强连通分量01]
- 计蒜之道 初赛 第一场 题解 dp 高效 网络流 最小割 最大流 ISAP 模板
- 【hh大神的】Tarjan + 缩点 模板
- 高斯消元法(Gauss Elimination) 分析 & 题解 & 模板——czyuan原创
- 高斯消元法(Gauss Elimination) 分析 & 题解 & 模板
- tarjan缩点模板 poj 2186
- 【模板】缩点 洛谷p3387
- 洛谷4512:【模板】多项式除法——题解
- 转:高斯消元法(Gauss Elimination) 分析 & 题解 & 模板——czyuan原创
- HDU 3652 B-number 题解(数位DP模板题)
- HDU 2767 Proving Equivalences Tanjan+缩点 直接当缩点的模板吧
- poj3177 tarjan缩点+割边 模板 【pascal】
- 高斯消元法(Gauss Elimination) 分析 & 题解 & 模板——czyuan原创