POJ3160强连通+spfa最长路(不错)
题意:
给你一个有向图,每个点上有一个权值,可正可负,然后给你一些链接关系,让你找到一个起点,从起点开始走,走过的边可以在走,但是拿过权值的点就不能再拿了,问最多能拿到多少权值?
思路:
首先我们考虑一个简单的问题,这个题目的负权值点肯定不拿,对于一个环(应该说是一个强连通分量)来说要拿可以一下全拿走(这个自己黄画画),那么一个环的价值是多少?就是这个强连通分量里所有正权值的和,这样我们一边强连通缩点,缩点之后变成了一个无环的有向图,然后在在上面跑最长路就行了,还有提醒一点,题目说的起点不固定,这个也好处理,我们只要在虚拟出来一个起点,到所有点的权值都是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最长路(不错)相关推荐
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur (SCC缩点,SPFA最长路,枚举反边)
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of hi ...
- P1931 套利-SPFA最长路与环的判断
题目连接套利 - 洛谷 制作不易,点赞走人 首先,每种货币看做一个点,map哈希赋值赋成若干个数字,货币之间转换关系看做两个节点之间的有向,注意是有向边,权值为比率,最长路的值就代表了兑换到该节点时的 ...
- *【HDU - 6201】transaction transaction transaction(树形dp 或 spfa最长路 或 网络流)
题干: 题目大意: 给出一棵n个顶点的树,每个点有一个权值,代表商品的售价,树上每一条边上也有一个权值,代表从这条边经过所需要的花费.现在需要你在树上选择两个点,一个作为买入商品的点,一个作为卖出商品 ...
- codevs 1183 泥泞的道路 二分+SPFA最长路
题目描述 Description CS有n个小区,并且任意小区之间都有两条单向道路(a到b,b到a)相连.因为最近下了很多暴雨,很多道路都被淹了,不同的道路泥泞程度不同.小A经过对近期天气和地形的科学 ...
- P1807 最长路 (SPFA写法)
题目描述 设 G 为有 n 个顶点的带权有向无环图,G 中各顶点的编号为 1 到 n,请设计算法,计算图 G 中 1,n 间的最长路径. 输入格式 输入的第一行有两个整数,分别代表图的点数 n 和边数 ...
- The Largest Clique UVA - 11324( 强连通分量 + dp最长路)
这题 我刚开始想的是 缩点后 求出入度和出度为0 的点 然后统计个数 用总个数 减去 然而 这样是不可以的 画个图就明白了... 如果 减去度为0的点 那么最后如果出现这样的情况是不可 ...
- BZOJ 2019 [Usaco2009 Nov]找工作:spfa【最长路】【判正环】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2019 题意: 奶牛们没钱了,正在找工作.农夫约翰知道后,希望奶牛们四处转转,碰碰运气. 而 ...
- 【SPFA】最长路(洛谷)
最长路 题目 设G为有n个顶点的有向无环图,G中各顶点的编号为1到n,且当为G中的一条边时有i < j.设w(i,j)为边的长度,请设计算法,计算图G中<1,n>间的最长路径. 输入 ...
- 计蒜客——闯关游戏 SPFA找最长路
问题描述 蒜头君在玩一个很好玩的游戏,这个游戏一共有至多 100 个地图,其中地图 1 是起点,房间 n 是终点.有的地图是补给站,可以加 ki点体力,而有的地图里存在怪物,需要消耗 ki 点体力,地 ...
最新文章
- 逻辑回归及常用模型分类评估方法
- SNMP功能开发简介 三 使用DEBUGMSG打印指定的信息
- 分享平时工作中那些给力的shell命令(更新版)
- 黄聪:WordPress 启用HTTPS设置(转)
- JAVA知识学习——类的修饰符
- Linux内核线程kernel thread详解--Linux进程的管理与调度
- redis修改端口号后还是占用6379_Redis分布式缓存分布式集群搭建
- 科学的分析猪八戒到底是什么猪,黑猪还是白猪?
- 库克跟乔布斯差几代iPhone? 解读iPhone十年变与不变
- 2017行进中的杂想,做一个极少数的历史
- css 选择器的应用
- sql2008r2服务器维护,Windows Server 2008 r2服务器上安装SQL Server 2008 r2的方法
- 基于labVIEW的学习(一)函数信号发生器
- 背阔肌(04):杠铃俯身划船
- 使用dd命令切割文件
- 小米打开或关闭MIUI9开发者选项
- Transformer如何用于视频?最新「视频Transformer」2022综述
- CF1364D Ehab‘s Last Corollary(思维,环,二分图,构造)
- 22届春季校招实习试水之路1(Java后端)
- c++项目 基于(多态,封装、继承类)——RPG小游戏 勇闯地下城
热门文章
- Apache activemq入门示例(maven项目)
- 《SolidWorks 2016中文版机械设计从入门到精通》——第1章 认识SolidWorks1.1 SolidWorks概述...
- lnmp、lamp、lnmpa一键安装包
- mysql 5.0 to mysql 5.1的BTREE索引问题
- 我看team work
- Mysql存储引擎MyIsAM和InnoDB区别
- IP分类以及特殊IP
- SQL Server 数据库状态选项
- jQueryui autocomplete使用示例
- 为什么程序员不擅长估算时间?