zoukankan      html  css  js  c++  java
  • 缩点tarjan

    给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。

    缩点含义:将一个环缩成一个点,然后把原本环上的点与外界相连的边,接到这个点上面
    换句话讲就是 tarjan求出的所有强连通分量都变成点,这样有向有环图就变成有向无环图(DAG),化简了问题
    对于这题,因为可以重复走边且只计算一次,那么如果有环的话为何不走,既然走了,那么这个环本身对答案其实就无意义了,所以用缩点

    缩点做法:
    工具:tarjan的dfn,low,stack,dfs
    思想:stack栈回溯的时候,环中点的权值都加到最先遍历的点上

    int tim=0;
    int color_num=0;
    void tarjan(int u){
    dfn[u]=low[u]=++tim;
    s[++top]=u;
    vis[u]=1;
    for(i,fi[u],nx){
    int v=e[i].to;
    if(!dfn[v])tarjan(v),chkmin(low[u],low[v]);
    else if(vis[v])chkmin(low[u],dfn[v]);
    }
    //回溯
    if(low[u]==dfn[u]){
    color_num++;
    while(s[top+1]!=u){//就是这里top+1
    color[s[top]]=color_num;
    sum[color_num]+=val[s[top]];//就这一步回加
    vis[s[top--]=false;//这里放top--
    }}}
    //回溯这么写也很优秀,反正u最后处理
    if(low[u]==dfn[u]){
    int v;
    while(v=s[top--]){
    point[v]=u;//指向u
    vis[v]=false;
    if(u==v)break;
    sum[u]+=sum[v];
    }}
    
    For(i,1,n)
    if(!dfn[i])tarjan(i,i);

    下面处理DAG中计算最大权值问题
    两种思路:
    1.记忆化dfs
    2.拓扑排序(针对存在后效性dp的手段)

    记得重新建DAG图

    法一:

    void dfs(int u){
    if(f[u])return;
    int res=0;
    for(i,fi[u],nx){
    int v=e[i].to;
    dfs(v);
    chkmax(res,f[v]);
    }
    f[u]+=res;
    }
    
    For(i,1,m)
    if(color[e[i].to]!=color[e[i].from])
    add(color[e[i].to],color[e[i].from]);
    
    For(i,1,color_num)
    if(!f[i])dfs(i),chkmax(ans,f[i]);

    法二:

    void topo(){
    queue<int>q;
    For(i,1,n)
    if(in[i]==0&&point[i]==i)q.push(i),f[i]=sum[i];
    while(!q.empty()){
    int u=q.front();q.pop();
    for(i,fi[u],nx){
    int v=e[i].to;
    in[v]--;
    chkmax(f[v],f[u]+sum[v]);
    if(!in[v])q.push(v);
    }}
    For(i,1,n)
    chkmax(ans,f[i]);
    }
  • 相关阅读:
    主线程——main线程
    进程和线程概念及原理
    抓取网贷之家的数据爬虫
    感知哈希算法的java实现
    最短路径—Dijkstra算法和Floyd算法
    关于图像特征提取
    hive学习之WordCount单词统计
    pig、hive以及hbase的作用
    zookeeper入门知识
    hadoop文件系统浅析
  • 原文地址:https://www.cnblogs.com/planche/p/9391532.html
Copyright © 2011-2022 走看看