zoukankan      html  css  js  c++  java
  • POJ 3249 Test for Job (拓扑排序+DP)

    <题目链接>

    题目大意:

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

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

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <iostream>
    using namespace std;
    #define REP(i,s,t) for(int i=s;i<=t;i++)
    #define clr(a,b) memset(a,b,sizeof(a))
    template<typename T>
    inline void read(T&x){     
      x=0;int f=1;char ch=getchar();
      while(ch<'0' ||ch>'9'){ if(ch=='-')f=-1; ch=getchar(); }
      while(ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }
      x*=f;
    }
    typedef long long ll;
    const int N = 1e5+5, M = 1e6+5;
    int w[N],in[N],out[N],head[N];
    int n,m,cnt;
    ll dp[N];
    struct Edge{ int to,nxt; }e[M];
    inline void init(){
        cnt=0;
        clr(head,-1);clr(dp,-0x3f);
        clr(in,0);clr(out,0);
    }
    inline void add(int u,int v){
        e[cnt]=(Edge){ v,head[u] };head[u]=cnt++;  
    }
    inline void TopoSort(){
        queue<int>q;
        REP(i,1,n) if(!in[i]){
            q.push(i);
            dp[i]=w[i];
        }
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=head[u];~i;i=e[i].nxt){
                int v=e[i].to;
                if(in[v]==0)continue;
                in[v]--;
                dp[v]=max(dp[v],dp[u]+w[v]);         //就这里进行简单的状态转移
                if(!in[v])q.push(v);
            }
        }
    }
    int main(){
        while(~scanf("%d%d",&n,&m)){
            init();
            REP(i,1,n)read(w[i]);
            REP(i,1,m){
                int u,v;read(u);read(v);
                add(u,v);
                out[u]++;in[v]++;
            }
            TopoSort();
            ll mx=-1e18;
            REP(i,1,n) if(!out[i]){
                mx=max(mx,dp[i]);
            }
            printf("%lld
    ",mx);
        }
    }
  • 相关阅读:
    (转载)链表环中的入口点 编程之美 leecode 学习
    leecode single numer
    leecode 树的平衡判定 java
    Let the Balloon Rise
    Digital Roots
    大数加法,A+B
    小希的迷宫
    畅通工程
    lintcode596- Minimum Subtree- easy
    lintcode597- Subtree with Maximum Average- easy
  • 原文地址:https://www.cnblogs.com/00isok/p/10888523.html
Copyright © 2011-2022 走看看