题意:

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

思路:

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

    简单介绍 selenium ​ selenium是一个用于测试web网页的自动化测试工具,它直接运行在浏览器中,模拟用户的操作.

  2. 面试必备——Java多线程与并发(二)

    1.synchroized相关(锁的是对象,不是代码) (1)线程安全问题的主要原因 存在共享数据(也称临界资源) 存在多线程共同操作这些共享数据 解决:同一时刻有且只有一个线程在操作共享数据,其他线 ...

  3. java 动态规划解决最大连续子数列和

    很多动态规划算法非常像数学中的递推.我们如果能找到一个合适的递推公式,就能很容易的解决问题.我们用dp[n]表示以第n个数结尾的最大连续子序列的和,这里第n个数必须在子序列中.于是存在以下递推公式: ...

  4. imagemagick 之 Fred's ImageMagick Scripts 在Ubuntu 下的实践

    Fred's ImageMagick Scripts 官网:http://www.fmwconcepts.com/imagemagick/index.php Windows 10 (64-bit) u ...

  5. python实现通过URL下载图片到本地服务器

    import os import urllib.request image_url = 'http://img.jingtuitui.com/759fa20190115144450401.jpg' f ...

  6. Python-生成器

    创建生成器 创建生成器需要两部步骤 定义一个包含yield语句的函数 调用第一步创建的函数得到生成器 def test(val,step): 2 print("函数开始执行") 3 ...

  7. .Net5下WebRequest、WebClient、HttpClient是否还存在使用争议?

    WebRequest.WebClient.HttpClient 是C#中常用的三个Http请求的类,时不时也会有人发表对这三个类使用场景的总结,本人是HttpClient 一把梭,也没太关注它们的内部 ...

  8. SqlServer存储过程的创建与使用

    什么是存储过程? T-SQL中的存储过程,非常类似于net语言中的方法,它可以重复调用.当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句. 这样就可以提高存储过程的性能. ...

  9. [树形DP]电子眼

    电 子 眼 电子眼 电子眼 题目描述 中山市石一个环境优美.气候宜人的小城市.因为城市的交通并不繁忙,市内的道路网很稀疏.准确地说,中山市有N-1条马路和N个路口,每条马路连接两个路口,每两个路口之间 ...

  10. 02-MySQL主要配置文件

    一.二进制日志log-bin 作用:主从复制 二.错误日志 log-err 默认关闭,记录严重的警告和错误信息,每次启动和关闭的详细信息 三.慢查询日志log 默认关闭,记录查询的sql语句,如果开启 ...