• POJ 3160 缩点+拓扑排序+简单dp


    题目链接: http://poj.org/problem?id=3160

    题目大意:

      给定一个有向图,每个点有权值,要求选定一个起点,从该点出发一直走,走出一条路径,该路径上的所有点的权值可取可不取,要求最大的权值和,注意可以重复走点,但是权值只可以加一次。

    分析:

      显然,如果权值<=0,一律赋为0,

      由输入数据,我们用Tarjan算法缩点得到一个有向无环图,同时注意每个强连通分量(SCC)的权值是该分量所含点的权值和;

      得到的有向无环图(DAG)可能是一个有多个入度为0的点的图,为了方便dp,进行拓扑排序,然后简单更新即可,具体见代码。

      (我自己对这类题目的理解就是:  进行拓扑排序可以方便dp,不会有后效性)

    代码:

    poj3160
      1 /*3160    Accepted    1436K    79MS    C++    2940B    2012-06-09 20:36:23*/
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <iostream>
      6 #include <algorithm>
      7 #include <vector>
      8 using namespace std;
      9 
     10 #define mpair make_pair
     11 #define pii pair<int,int>
     12 #define MM(a,b) memset(a,b,sizeof(a));
     13 typedef long long lld;
     14 typedef unsigned long long u64;
     15 template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;}
     16 template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;}
     17 #define maxn 30020
     18 
     19 int n,m;
     20 int val[maxn];
     21 vector<int>g[maxn], adj[maxn];
     22 
     23 void Read(){
     24     for(int i=0;i<n;++i){
     25         scanf("%d", val+i);
     26         if( val[i]<0 ) val[i]= 0;
     27     }
     28     for(int i=0;i<n;++i) g[i].clear(); /// clear();
     29     for(int i=1;i<=m;++i){
     30         int x,y;
     31         scanf("%d%d", &x, &y);
     32         g[x].push_back(y);
     33     }
     34 }
     35 
     36 int c[maxn];
     37 int Bcnt, Index, Top;
     38 int low[maxn], dfn[maxn], stack[maxn], belong[maxn];
     39 bool vis[maxn];
     40 void Init_tarjan(){
     41     Bcnt= Index= Top= 0;
     42     for(int i=0;i<n;++i) low[i]= dfn[i]= vis[i]= 0;
     43 }
     44 void Tarjan(int u){
     45     stack[++Top]= u;
     46     vis[u]= 1;
     47     low[u]= dfn[u]= ++Index;
     48     for(int i=0;i<g[u].size();++i){
     49         int v= g[u][i];
     50         if( !dfn[v] ){
     51             Tarjan(v);
     52             up_min( low[u], low[v] );
     53         }
     54         else if( vis[v] )
     55             up_min( low[u], dfn[v] );
     56     }
     57     if( low[u]==dfn[u] ){
     58         c[ ++Bcnt ] = 0;
     59         int v;
     60         do{
     61             v= stack[Top--];
     62             vis[v]= 0;
     63             belong[v]= Bcnt;
     64             c[Bcnt]+= val[v];
     65         }while(u!=v);
     66     }
     67 }
     68 
     69 int in[maxn];
     70 void dfs(int u){
     71     vis[u]= 1;
     72     for(int i=0;i<g[u].size();++i){
     73         int v= g[u][i];
     74         if( belong[u]!=belong[v] ){
     75             adj[ belong[u] ].push_back( belong[v] );
     76             in[ belong[v] ]++;
     77         }
     78         if( !vis[v] ) dfs(v);
     79     }
     80 }
     81 
     82 int *que;
     83 int dp[maxn];
     84 int Topsort(){
     85     int head=0, tail= 0;
     86     fill( dp, dp+1+Bcnt, 0 );
     87     for(int i=1;i<=Bcnt;++i) if( in[i]==0 ) { que[tail++]= i; dp[i]= c[i];}
     88     while( head<tail ){
     89         int u= que[head++];
     90         for(int i=0;i<adj[u].size();++i){
     91             int v= adj[u][i];
     92             if( --in[v] == 0 )
     93                 que[tail++]= v;
     94         }
     95     }
     96 
     97     for(int i=0;i<tail;++i){
     98         int u= que[i];
     99         for(int j=0;j<adj[u].size();++j){
    100             int v= adj[u][j];
    101             up_max( dp[v], dp[u]+c[v] );
    102         }
    103     }
    104     return *max_element( dp+1, dp+1+Bcnt );
    105 }
    106 
    107 int solve(){
    108     Init_tarjan();
    109     for(int i=0;i<n;++i){
    110         if( !dfn[i] )
    111             Tarjan(i);
    112     }
    113 
    114     MM( vis, 0 );
    115     for(int i=1;i<=Bcnt;++i) adj[i].clear(), in[i]= 0;
    116     for(int i=0;i<n;++i){
    117         if( !vis[i] )
    118             dfs(i);
    119     }
    120     que= stack; ///
    121     return Topsort();
    122 }
    123 
    124 int main()
    125 {
    126     // freopen("poj3160.in","r",stdin);
    127     while( cin>>n>>m ){
    128         Read();
    129         cout<< solve() << endl;
    130     }
    131 }
  • 相关阅读:
    Java泛型T与?
    json解析出现:java.lang.ClassCastException: net.sf.ezmorph.bean.MorphDynaBean cannot be cast to XXX
    Html 项目使用自定义字体文件问题
    修复 WordPress 通过邮箱 找回密码时的链接无效&新用户注册时提示的链接无效
    Linux查询进程和结束进程
    Linux --- 程序后台运行的几种方法
    bash_profile和bashsrc的区别
    在CentOS中安装与配置Server JRE 8
    JRE和JDK的区别
    java中静态代码块详解
  • 原文地址:https://www.cnblogs.com/yimao/p/2543493.html
Copyright © 2020-2023  润新知