• POJ 3249 Test for Job (拓扑排序+DP)


    <题目链接>

    题目大意:

    给定一个有向图(图不一定连通),每个点都有点权(可能为负),让你求出从源点走向汇点的路径上的最大点权和。

    解题分析:
    想到拓扑排序就好做了,然后在拓扑的过程中进行简单的状态转移。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <queue>
    using namespace std;
    const int maxn = 1e5 + 7,M = 1e6 + 7;
    int n , m;
    std::vector<long long> g[maxn];
    int ou[maxn],in[maxn];
    long long dp[maxn],w[maxn];
    
    struct Edge{ int to,nxt; }e[M];
    
    int cnt,head[maxn];
    inline void add(int u,int v){
        e[cnt]=(Edge){ v,head[u] };head[u]=cnt++;  
    }
    
    void init(){
        cnt = 0;
        memset(head,-1,sizeof head);
        memset(dp,-0x3f,sizeof dp);
        memset(in,0,sizeof in);
        memset(ou,0,sizeof ou);
    }
    
    void topsort(){
        queue<int> q;
        for(int i = 1;i <= n ;i ++){
            if(!in[i]) {
                q.push(i);
                dp[i] = w[i];
            }
        }
    
        while(!q.empty()){
            int now = q.front() ; q.pop();
            for(int i = head[now]; ~i; i = e[i].nxt){
                int v = e[i].to;
                if(in[v] == 0) continue;
                in[v] --;
                dp[v] = max(dp[v],dp[now] + w[v]);
                if(!in[v]) q.push(v);
            }
        }
    }
    
    int main(int argc, char const *argv[])
    {
        //int n , m;
        while(~scanf("%d %d",&n,&m)){
            init();
            for(int i = 1;i <= n; i ++) scanf("%lld",&w[i]);
                for(int i = 1;i <= m;i ++){
                    int u , v;
                    scanf("%d %d",&u,&v);
                    add(u,v);
                    ou[u] ++; in[v] ++;
                }
                topsort();
                long long mx = -1e18;
                for(int i= 1;i <= n; i ++){
                    if(!ou[i]){
                        mx = max(mx,dp[i]);
                    }
                }
                printf("%lld
    ", mx);
        }
        return 0;
    }
  • 相关阅读:
    开源Jabber(XMPP) IM服务器介绍
    ejabberd、jabber、jabberd、xmpp辨析
    分布式与集群的区别
    浅谈Javascript事件模拟
    理清javascript的相关概念 DOM和BOM
    js基础学习第一天(关于DOM和BOM)一
    处理机调度和死锁
    C++11 之 " = delete "
    小数的二进制表示
    二进制数的插入
  • 原文地址:https://www.cnblogs.com/DWVictor/p/11342802.html
Copyright © 2020-2023  润新知