题意:有一张 n 点 m 边的有向无环图,每个点有各自的权值,可正可负,现在从一个点开始走,一直走到不能走到其他点为止,每经过一个点,可以选择获得或不获得它的权值,每个点可以走多次,但是权值只能获得一次,问最后最多能够获得多少权值。

每个点可以走多次,权值只能获得一次,路过的时候权值可以不获得,所以我们只需要考虑正的权值就行了。在一个强连通分量中的点的权值我们都能获得,所以先缩点,得到一个有向无环图,然后从每个入度为 0 的点开始DFS,累计得到的最大权值就行。

 #include<stdio.h>
#include<string.h>
#include<stack>
#include<queue>
using namespace std; const int maxn=3e4+;
const int maxm=2e5+; int head[][maxn],point[][maxm],nxt[][maxm],size[];
int n,t,scccnt;
int stx[maxn],low[maxn],scc[maxn],num[maxn],id[maxn],v[maxn];
int dp[maxn];
stack<int>S; int max(int a,int b){return a>b?a:b;} void init(){
memset(head,-,sizeof(head));
size[]=size[]=;
memset(num,,sizeof(num));
memset(id,,sizeof(id));
memset(dp,-,sizeof(dp));
} void add(int a,int b,int c=){
point[c][size[c]]=b;
nxt[c][size[c]]=head[c][a];
head[c][a]=size[c]++;
} void dfs(int s){
stx[s]=low[s]=++t;
S.push(s);
for(int i=head[][s];~i;i=nxt[][i]){
int j=point[][i];
if(!stx[j]){
dfs(j);
low[s]=min(low[s],low[j]);
}
else if(!scc[j]){
low[s]=min(low[s],stx[j]);
}
}
if(low[s]==stx[s]){
scccnt++;
while(){
int u=S.top();S.pop();
scc[u]=scccnt;
num[scccnt]+=v[u]>?v[u]:;
if(s==u)break;
}
}
} void setscc(){
memset(stx,,sizeof(stx));
memset(scc,,sizeof(scc));
t=scccnt=;
for(int i=;i<=n;++i)if(!stx[i])dfs(i);
for(int i=;i<=n;++i){
for(int j=head[][i];~j;j=nxt[][j]){
int k=point[][j];
if(scc[i]!=scc[k]){
add(scc[i],scc[k],);
id[scc[k]]++;
}
}
}
} int dfs1(int s){
if(~dp[s])return dp[s];
int maxx=;
for(int i=head[][s];~i;i=nxt[][i]){
int j=point[][i];
maxx=max(maxx,dfs1(j));
}
dp[s]=maxx+num[s];
return dp[s];
} int main(){
int m;
while(scanf("%d%d",&n,&m)!=EOF){
init();
for(int i=;i<=n;++i)scanf("%d",&v[i]);
while(m--){
int a,b;
scanf("%d%d",&a,&b);
a++;
b++;
add(a,b);
}
setscc();
int ans=;
for(int i=;i<=scccnt;++i){
if(!id[i])ans=max(ans,dfs1(i));
}
printf("%d\n",ans);
}
return ;
}

poj3160 强连通+记忆化搜索的更多相关文章

  1. poj3592 强连通+记忆化搜索

    题意:有一片 n*m 的矿地,每一格有矿.或这传送门.或者挡路岩石.除了岩石不能走以外,其他的格子都能够向右或向下走,走到一个非岩石的格子.对于每一个矿点,经过它就能得到它的所有矿石,而对于每一个传送 ...

  2. ZOJ3795 Grouping(强连通分量+缩点+记忆化搜索)

    题目给一张有向图,要把点分组,问最少要几个组使得同组内的任意两点不连通. 首先考虑找出强连通分量缩点后形成DAG,强连通分量内的点肯定各自一组,两个强连通分量的拓扑序能确定的也得各自一组. 能在同一组 ...

  3. LightOJ1417 Forwarding Emails(强连通分量+缩点+记忆化搜索)

    题目大概是,每个人收到信息后会把信息发给他认识的一个人如此下去,问一开始要把信息发送给谁这样看到信息的人数最多. 首先找出图中的SCC并记录每个SCC里面的点数,如果传到一个SCC,那么里面的人都可以 ...

  4. BNU 20860——Forwarding Emails——————【强连通图缩点+记忆化搜索】

    Forwarding Emails Time Limit: 1000ms Memory Limit: 131072KB This problem will be judged on UVA. Orig ...

  5. [ACM_动态规划] 数字三角形(数塔)_递推_记忆化搜索

    1.直接用递归函数计算状态转移方程,效率十分低下,可以考虑用递推方法,其实就是“正着推导,逆着计算” #include<iostream> #include<algorithm> ...

  6. 【BZOJ-3895】取石子 记忆化搜索 + 博弈

    3895: 取石子 Time Limit: 1 Sec  Memory Limit: 512 MBSubmit: 263  Solved: 127[Submit][Status][Discuss] D ...

  7. hdu3555 Bomb (记忆化搜索 数位DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=3555 Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  8. zoj 3644(dp + 记忆化搜索)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4834 思路:dp[i][j]表示当前节点在i,分数为j的路径条数,从 ...

  9. loj 1044(dp+记忆化搜索)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26764 思路:dp[pos]表示0-pos这段字符串最少分割的回文 ...

随机推荐

  1. 《BI那点儿事》数据流转换——数据转换

    数据转换执行类似于T-SQL中的函数CONVERT或CAST的功能.数据转换的编辑界面如图,选择需要转换的列,在DataType下拉列表中选择需要的数据类型.Output Alias栏内设置输出时使用 ...

  2. implicit operator

    class Digit { public Digit(double d) { val = d; } public double val; // ...other members // User-def ...

  3. exception

    SQL> -- 例外 exceptionSQL> -- 1/0SQL> ed已写入 file afiedt.buf 1  declare  2   pnum number := 0; ...

  4. 前端开发流程之(线上)绝对地址(图片+css+js)

    重要提醒:前端写完-----发邮件通知项目组 1:写好的前段资源包上传到SVN上之后,相关的图片.CSS.js文件要换成线上地址给后台开发. 2:图片-----压缩(https://tinypng.c ...

  5. Krajee 文件上传

    http://plugins.krajee.com/file-input/demo#ajax-uploads 插件官网 项目要个好看点的上传控件,于是搜到了这个. git的地址是 https://gi ...

  6. java判断时间是否是今天

    SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd"); Date d1=format.parse(FHavetime ...

  7. Java 实现word 中写入文字图片的解决方案

    JAVA生成WORD文件的方法目前有以下两种方式: 一种是jacob 但是局限于windows平台 往往许多JAVA程序运行于其他操作系统 在此不讨论该方案; 一种是poi但是他的excel处理很程序 ...

  8. Shell 教程

    Shell 是一个用C语言编写的程序,它是用户使用Linux的桥梁.Shell既是一种命令语言,又是一种程序设计语言. Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操 ...

  9. (35)odoo中widget

    widget大全: many2many_tagsone2many_listselectionprogressbarselectionstatusbarhandlemonetarymail_thread ...

  10. 类库、委托、is as运算符、泛型集合

    类库: 说白了,就是让别人调用你写的方法,并且不让别人看到你是怎么实现的. 如果有功能你不会做,需要别人帮忙,那么你的同事可以帮你写好一个类,然后你来调用这个类中的方法,完成你的项目. 1.C#源代码 ...