题意:

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

思路:

      首先我们考虑一个简单的问题,这个题目的负权值点肯定不拿,对于一个环(应该说是一个强连通分量)来说要拿可以一下全拿走(这个自己黄画画),那么一个环的价值是多少?就是这个强连通分量里所有正权值的和,这样我们一边强连通缩点,缩点之后变成了一个无环的有向图,然后在在上面跑最长路就行了,还有提醒一点,题目说的起点不固定,这个也好处理,我们只要在虚拟出来一个起点,到所有点的权值都是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. POJ-2253(最短路变形+dijikstra算法+求解所有路径中所有最长边中的一个最小值)

    frogger POJ-2253 这题的代码特别像prim求解最小生成树的代码,其实两者本来也很像. 这里的d数组不再维护的起点到该点的最短距离了,而是路径中的最长距离. #include<io ...

  2. 解决:layUI数据表格+简单查询

    解决:layUI数据表格+简单查询 最近在用layui写项目,在做到用户查询时,发现在layui框架里只有数据表格,不能增加查询.于是自己摸索了一下,写个笔记记录一下. 我想要的效果: 1.定义查询栏 ...

  3. 【Arduino学习笔记03】面包板基础知识

    终端带 这里有一块面包板,它后面的黏贴纸被撕去了.你可以看到很多在底部的平行金属条. 金属条的结构:金属条的顶部有一个小夹子.这些夹子能将一条导线或某个部件的引脚固定在塑料洞上,使它们放置在适当的位置 ...

  4. CMU数据库(15-445)Lab3- QUERY EXECUTION

    Lab3 - QUERY EXECUTION 实验三是添加对在数据库系统中执行查询的支持.您将实现负责获取查询计划节点并执行它们的executor.您将创建执行下列操作的executor Access ...

  5. C# 基础 - 委托、事件

    1. 委托 sequenceDiagram 方法->>委托: 返回值和入参一样 委托->>方法: 调用委托就是调用绑定的方法 delegate int NumTest(int ...

  6. SQL练习——LeetCode解题和总结(2)

    602. Friend Requests II: Who Has the Most Friends[M] 一.表信息 In social network like Facebook or Twitte ...

  7. java IO NIO BIO 最权威的总结

    1. BIO (Blocking I/O) 1.1 传统 BIO 1.2 伪异步 IO 1.3 代码示例 1.4 总结 2. NIO (New I/O) 2.1 NIO 简介 2.2 NIO的特性/N ...

  8. 关于HashMap的一些思考

    一.HashMap的负载因子的作用 当 HashMap 中的元素个数(包含链表.红黑树上的元素)达到数组长度的0.75倍的时候,开始扩容.   二.HashMap的负载因子为什么是0.75 主要是为了 ...

  9. Android 系统开发做什么?

    题外话 18 年我从 Android 应用开发转 Framework 层开发了,从此开启了 996 幸福生活,博客技术文更新基本停滞了,被工作占据了过多的精力,实在没时间像以前一样拟稿.写作,实践.反 ...

  10. 鸿蒙运行报错:Failure[INSTALL_PARSE_FAILED_USESDK_ERROR] Error while Deploying HAP

    问题描述 近期,使用DevEco-Studio新建手机类型的工程,编译成功,发布到模拟器(鸿蒙P40)时出错,如下图: 原因分析 本地DevEco-Studio使用的SDK版本与设备(P40)不匹配导 ...