题意:

      给你一个有向图,每个点上有一个权值,可正可负,然后给你一些链接关系,让你找到一个起点,从起点开始走,走过的边可以在走,但是拿过权值的点就不能再拿了,问最多能拿到多少权值?

思路:

      首先我们考虑一个简单的问题,这个题目的负权值点肯定不拿,对于一个环(应该说是一个强连通分量)来说要拿可以一下全拿走(这个自己黄画画),那么一个环的价值是多少?就是这个强连通分量里所有正权值的和,这样我们一边强连通缩点,缩点之后变成了一个无环的有向图,然后在在上面跑最长路就行了,还有提醒一点,题目说的起点不固定,这个也好处理,我们只要在虚拟出来一个起点,到所有点的权值都是0就行了,这样就能一遍spfa搞定了,千万别跑n遍spfa那样太无脑了。

虽然简单,但感觉这个题目还不错,挺有实际意义的。

#include<stack>

#include<queue>

#include<stdio.h>

#include<string.h>

#define N_node 30000 + 10

#define N_edge 200000 + 50

#define INF 1000000000

using namespace std;

typedef struct

{

    int to ,cost ,next;

}STAR;

typedef struct

{

    int a ,b;

}EDGE;

EDGE E[N_edge];

STAR E1[N_edge] ,E2[N_edge];

int list1[N_node] ,list2[N_node] ,tot;

int Belong[N_node] ,mark[N_node] ,cont;

int s_x[N_node] ,get[N_node] ,cost[N_node];

stack<int>sk;

void add(int a ,int b ,int c)

{

    E1[++tot].to = b;

    E1[tot].cost = c;

    E1[tot].next = list1[a];

    list1[a] = tot;

    E2[tot].to = a;

    E2[tot].cost = c;

    E2[tot].next = list2[b];

    list2[b] = tot;

}

void DFS1(int s)

{

    mark[s] = 1;

    for(int k = list1[s] ;k ;k = E1[k].next)

    if(!mark[E1[k].to]) DFS1(E1[k].to);

    sk.push(s);

}

void DFS2(int s)

{

    mark[s] = 1;

    Belong[s] = cont;

    for(int k = list2[s] ;k ;k = E2[k].next)

    if(!mark[E2[k].to]) DFS2(E2[k].to);

}

void Spfa(int s ,int n)

{

    memset(mark ,0 ,sizeof(mark));

    for(int i = 0 ;i <= n ;i ++)

    s_x[i] = -INF;

    queue<int>q;

    q.push(s);

    mark[s] = 1;

    s_x[s] = 0;

    while(!q.empty())

    {

        int xin ,tou;

        tou = q.front();

        q.pop();

        mark[tou] = 0;

        for(int k = list1[tou] ;k ;k = E1[k].next)

        {

            xin = E1[k].to;

            if(s_x[xin] < s_x[tou] + E1[k].cost)

            {

                s_x[xin] = s_x[tou] + E1[k].cost;

                if(!mark[xin])

                {

                    mark[xin] = 1;

                    q.push(xin);

                }

            }

        }

    }

}

int main ()

{

    int n ,m ,i ,a ,b;

    while(~scanf("%d %d" ,&n ,&m))

    {

        for(i = 1 ;i <= n ;i ++)

        scanf("%d" ,&cost[i]);

        memset(list1 ,0 ,sizeof(list1));

        memset(list2 ,0 ,sizeof(list2));

        tot = 1;

        for(i = 1 ;i <= m ;i ++)

        {

            scanf("%d %d" ,&a ,&b);

            a ++ ,b ++;

            add(a ,b ,1);

            E[i].a = a ,E[i].b = b;

        }

        while(!sk.empty()) sk.pop();

        memset(mark ,0 ,sizeof(mark));

        for(i = 1 ;i <= n ;i ++)

        if(!mark[i]) DFS1(i);

        memset(mark ,0 ,sizeof(mark));

        cont = 0;

        while(!sk.empty())

        {

            int to = sk.top();

            sk.pop();

            if(mark[to]) continue;

            ++cont;

            DFS2(to);

        }

        memset(get ,0 ,sizeof(get));

        for(i = 1 ;i <= n ;i ++)

        if(cost[i] >= 0) get[Belong[i]] += cost[i];

        memset(list1 ,0 ,sizeof(list1));

        memset(list2 ,0 ,sizeof(list2));

        tot = 1;

        for(i = 1 ;i <= n ;i ++)

        add(0 ,i ,get[i]);

        for(i = 1 ;i <= m ;i ++)

        {

            a = Belong[E[i].a];

            b = Belong[E[i].b];

            if(a == b) continue;

            add(a ,b ,get[b]);

        }

        Spfa(0 ,n);

        int ans = 0;

        for(i = 1 ;i <= n ;i ++)

        if(ans < s_x[i]) ans = s_x[i];

        printf("%d\n" ,ans);

    }

    return 0;

}

POJ3160强连通+spfa最长路(不错)的更多相关文章

  1. 【bzoj1179】[Apio2009]Atm Tarjan缩点+Spfa最长路

    题目描述 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每 ...

  2. bzoj1179: [Apio2009]Atm 【缩点+spfa最长路】

    题目传送门 Description Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruser i 银行的 ATM 取款机.令人奇怪的是,S ...

  3. XYZZY spfa 最长路 判环

    题意: 有n个点  m条边  每个边有权值 一开始有一百血  每次经过一条路都会加上其权值 判断是否能够到达n 显然  有正环的时候肯定能够到达 最短路好题!!!!!!! 显用folyed判断是否联通 ...

  4. poj 1932 XYZZY(spfa最长路+判断正环+floyd求传递闭包)

    XYZZY Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 4154   Accepted: 1185 Description ...

  5. HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6201 题意:给出一棵树,每个点有一个权值,代表商品的售价,树上每一条边上也有一个权值,代表从这条边经过 ...

  6. Tarjan缩点+Spfa最长路【p3627】[APIO2009] 抢掠计划

    Description Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruseri 银行的 ATM 取款机.令人奇怪的是,Siruseri ...

  7. [BZOJ1663] [Usaco2006 Open]赶集(spfa最长路)

    传送门 按照时间t排序 如果 t[i] + map[i][j] <= t[j],就在i和j之间连一条边 然后spfa找最长路 #include <queue> #include &l ...

  8. [luogu3627 APIO2009] 抢掠计划 (tarjan缩点+spfa最长路)

    传送门 Description Input 第一行包含两个整数 N.M.N 表示路口的个数,M 表示道路条数.接下来 M 行,每行两个整数,这两个整数都在 1 到 N 之间,第 i+1 行的两个整数表 ...

  9. BZOJ 3887/Luogu P3119: [Usaco2015 Jan]Grass Cownoisseur (强连通分量+最长路)

    分层建图,反向边建在两层之间,两层内部分别建正向边,tarjan缩点后,拓扑排序求一次1所在强连通分量和1+n所在强联通分量的最长路(长度定义为路径上的强联通分量内部点数和).然后由于1所在强连通分量 ...

随机推荐

  1. js导出execl 兼容ie Chrome Firefox各种主流浏览器(js export execl)

    第一种导出table布局的表格 1 <html> 2 3 <head> 4 <meta charset="utf-8"> 5 <scrip ...

  2. flutter简易教程

    跟Java等很多语言不同的是,Dart没有public protected private等关键字,如果某个变量以下划线 _ 开头,代表这个变量在库中是私有的.Dart中变量可以以字母或下划线开头,后 ...

  3. sort函数用于vector向量的排序

    参考资料: 关于C++中vector和set使用sort方法进行排序 作者注:这篇文章写得相当全面,包括对vector和set中不同数据类型(包括结构体)的排序,还有一些还没看懂--特作此摘录,供当前 ...

  4. P1089_津津的储蓄计划(JAVA语言)

    package 顺序与分支; /* * 题目描述 津津的零花钱一直都是自己管理.每个月的月初妈妈给津津300元钱, 津津会预算这个月的花销,并且总能做到实际花销和预算的相同. 为了让津津学习如何储蓄, ...

  5. c++ 反汇编 堆变量

    malloc _malloc 0037E8C0 8B FF mov edi,edi 0037E8C2 55 push ebp 0037E8C3 8B EC mov ebp,esp 0037E8C5 6 ...

  6. 攻防世界 reverse 进阶 15-Reversing-x64Elf-100

    15.Reversing-x64Elf-100 这题非常简单, 1 signed __int64 __fastcall sub_4006FD(__int64 a1) 2 { 3 signed int ...

  7. java.lang.IllegalArgumentException: MALFORMED

    java.lang.IllegalArgumentException: MALFORMED at java.util.zip.ZipCoder.toString(ZipCoder.java:58) a ...

  8. Python基础之异常定义

    技术背景 在各类python的项目中,总会涉及到项目自身相关的一些约束条件.这些约束条件体现在,当用户输入的参数或者文件不符合项目要求时,就拒绝这个参数的输入并且播报出来,提醒用户自行修改,而这一过程 ...

  9. 如何配置Nginx,实现http访问重定向到https?

    现在越来越多的网站,当我们输入域名时,会自动重定向到https,我们只需要简单修改下Nginx配置文件/usr/local/nginx/conf/nginx.conf(根据个人的实际存储路径)即可. ...

  10. java学习(更新中)

    class Test { public static void main(String[] args) { System.out.println("Hello World!"); ...