zoukankan      html  css  js  c++  java
  • [POJ3249]Test for Job [拓扑排序+DAG上的最长路径]

    给定一张带点权的DAG 求一条入度为0节点到出度为0节点的最长路

    把点权转化为边权(同时多源转化成单源):边u->v的权值为W[v],这样入度为0的节点权值会被遗漏,新开一个点0向入度为0的点u连有向边,权值为W[u],这样就只有0是入度为0的点了。

    先进行拓扑排序,再求出最长路径(利用DAG分层的性质可以在线性时间内求出最长路)

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <cstdio>
     6 using namespace std;
     7 typedef long long LL;
     8 
     9 template<class T> void read(T & x){
    10   register int c = getchar(), f = 1; x = 0;
    11   while(!isdigit(c)){if (c == '-') f = -1; c = getchar();}
    12   while(isdigit(c)) x = x*10+(c&15), c = getchar();
    13   x *= f;
    14 }
    15 const int N = 100005;
    16 struct Edge{int v, w, next;}G[N*20];
    17 int n, m, s, head[N], tot,  ind[N], out[N], W[N]; LL dis[N], ans = -123023423423;
    18 void toposort(int s) {
    19   int topo[N], cnt = 0;
    20   topo[++cnt] = 0;
    21   for(int k = 0; k <= cnt; ++k)
    22     for(int i = head[topo[k]]; i; i = G[i].next) {
    23       int v = G[i].v;
    24       ind[v]--;
    25       if (ind[v]==0) topo[++cnt] = v;
    26     }
    27   memset(dis,0xc0,sizeof(dis));dis[s] = 0;
    28   for(int k = 0; k <= cnt; ++k)
    29     for(int i = head[topo[k]]; i; i = G[i].next) {
    30       int v = G[i].v, w = G[i].w;
    31       dis[v] = max(dis[topo[k]]+w, dis[v]);
    32     }
    33 }
    34 
    35 inline void add(int u, int v, int w) {
    36   G[++tot].v=v, G[tot].w=w, G[tot].next=head[u];head[u]=tot;
    37   ind[v]++, out[u]++;
    38 }
    39 
    40 int main(void){
    41   while(scanf("%d%d", &n, &m) == 2){
    42     memset(head,0,sizeof(head));tot=0;memset(ind,0,sizeof(ind));memset(out,0,sizeof(out));
    43     ans = 0xc0c0c0c0c0c0c0c0;
    44     for(int i = 1; i <= n; ++i) read(W[i]);
    45     for(int u, v, i = 1; i <= m; ++i) {
    46       read(u), read(v);
    47       add(u, v, W[v]);
    48     } 
    49     for(int i = 1; i <= n; ++i) {
    50       if (!ind[i]) add(0,i,W[i]);
    51     }
    52     toposort(s);
    53     for(int i = 1; i <= n; ++i) {
    54       if (!out[i]) ans = max(ans, dis[i]);
    55     }
    56     cout << ans << '
    ';
    57   }
    58   return 0;
    59 }
    View Code
  • 相关阅读:
    我的日常笔记
    html元素是如何占据空间和定位的
    jdbc和数据库的应用
    java笔记之String的应用
    java笔记之静态修饰附和单例设计模式
    java笔记
    本人对于JavaScript的一些总结
    JavaScript 轮播图
    h5简单布局练习
    有一个八位数,个位数+十位数+百位数+千位数一直加到千万位数的和除以7能等于0.。。。
  • 原文地址:https://www.cnblogs.com/storz/p/8550884.html
Copyright © 2011-2022 走看看