luoguP3387 【模板】缩点
来源:互联网 发布:女网络歌手 编辑:程序博客网 时间:2024/05/16 15:38
题目背景
缩点+DP
题目描述
给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。
允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。
输入输出格式
输入格式:
第一行,n,m
第二行,n个整数,依次代表点权
第三至m+2行,每行两个整数u,v,表示u->v有一条有向边
输出格式:
共一行,最大的点权之和。
输入输出样例
输入样例#1:
2 2
1 1
1 2
2 1
输出样例#1:
2
说明
n<=10^4,m<=10^5,|点权|<=1000 算法:Tarjan缩点+DAGdp
分析:
tarjan缩点的模板可以说是基本不会
实际上还是很好写的
dp的时候用的是记搜(舒老师表示用spfa就可以了)
tip
for (int i=1;i<=n;i++) if (!pre[i]) dfs(i);
上面的语句一定不要忘了,这样可以避免图不连通的情况
题目说|点权|<=1000,实际上好像也没有特意构造吧
ans的初始值设成0就可以了(没有特殊的处理啊)
//这里写代码片#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int INF=0x33333333;const int N=10005;struct node{ int x,y,nxt;};node e[N*10],way[N*10];int a[N],val[N],n,m,cnt=0;int ste[N],stw[N],tot=0,totw=0,clo=0;int pre[N],low[N],sta[N],top=0,scc[N],f[N];bool vis[N];void add(int u,int w){ tot++; e[tot].x=u;e[tot].y=w;e[tot].nxt=ste[u];ste[u]=tot;}void ad(int u,int w){ totw++; way[totw].x=u;way[totw].y=w;way[totw].nxt=stw[u];stw[u]=totw;}void dfs(int u){ low[u]=pre[u]=++clo; sta[++top]=u; for (int i=ste[u];i;i=e[i].nxt) { int v=e[i].y; if (!pre[v]) { dfs(v); low[u]=min(low[u],low[v]); } else if (!scc[v]) //经过的点不能是scc里的点 low[u]=min(low[u],pre[v]); } if (low[u]==pre[u]) { cnt++; int sum=0; for(;;) { int x=sta[top--]; scc[x]=cnt; sum+=a[x]; //最大权值 if (x==u) break; } val[cnt]=sum; } }int dp(int now){ if (vis[now]) return f[now]; vis[now]=1; int &ans=f[now]; ans=0; //|点权|<=1000 for (int i=stw[now];i;i=way[i].nxt) ans=max(ans,dp(way[i].y)); ans+=val[now]; return ans;}void build(){ for (int i=1;i<=tot;i++) { int x=e[i].x; int y=e[i].y; if (scc[x]!=scc[y]) ad(scc[x],scc[y]); }}int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&a[i]); for (int i=1;i<=m;i++) { int u,w; scanf("%d%d",&u,&w); add(u,w); } memset(pre,0,sizeof(pre)); memset(scc,0,sizeof(scc)); for (int i=1;i<=n;i++) //不能忘了 if (!pre[i]) dfs(i); build(); int ans=0; memset(vis,0,sizeof(vis)); memset(f,0,sizeof(f)); for (int i=1;i<=cnt;i++) ans=max(ans,dp(i)); printf("%d",ans); return 0;}
阅读全文
0 0
- luoguP3387 【模板】缩点
- Tarjan缩点模板
- 高效率 kosaraju+缩点 模板
- 【模板】缩点 洛谷p3387
- 洛谷 P3387 【模板】缩点
- poj 2186 DAG+缩点+tarjan模板 (模板待消化
- 模板整理: 图论---tarjan缩点/桥/割点
- 强连通分量缩点的模板
- 【hh大神的】Tarjan + 缩点 模板
- tarjan缩点模板 poj 2186
- 双联通分量缩点模板
- 强连通分量缩点模板
- tarjan算法缩点构图(模板)
- Tarjan 缩点模板(洛谷P3387)
- Tarjan缩点模板(洛谷P3387)
- 模板:强连通分量和缩点
- 【模板】Tarjan 缩点 + 最长路
- tarjan缩点/求桥模板
- 数据结构上机3
- python操作配制文件
- lcs模板
- 速度与激情
- 【bzoj2802】[Poi2012]Warehouse Store
- luoguP3387 【模板】缩点
- Ubuntu配置php环境
- bzoj 3881: [Coci2015]Divljak AC自动机+树链的并+树状数组
- 判断链表中是否有环 ----- 有关单链表中环的问题
- linux mysql 常用命令
- Python高级编程——12.(2)系统编程之多线程
- WorkerMan学习篇:连接mysql
- 树莓派烧写镜像
- NYOJ 大猪生小猪