[HDU 1317]XYZZY[SPFA变形][最长路]
题意:
一个图, 点权代表走到该点可获得的能量值. 可正可负. 一个人从1 号出发,带有100点能量. 问是否有一种方案可使人在能量值>0的时候走到n.
思路:
这个题首先要注意点权. 其实就是这点的所有入边的边权都等于这点的点权.
要找长路, 而非最短路. 但是可以借助最短路的算法SPFA求.
最短路的算法SFPA主要是 队列 + 松弛
松弛操作直接关系到我们运行算法的目的----求最短路
如果与该点相邻的下一个点到源的距离可以因为通过该点中转而缩短 ,则更新此下一个点到源的最短距离, 也就相当于选择了走 经过该点中转这条路.(有点dp的意思?)
如果更新成功, 则意味着刚刚被更新的这一点有可能继续更新它临接的点. (如果没有被更新的话, 那么与它邻接的点, 要么已经被更新过(靠近源的,已出队的), 要么在队列中(靠近源的,在队列中), 要么还尚未涉及(远离源的), 就算询问也不可能执行松弛操作)
而队列的优化(相对于Bellman-Ford)则是把整个松弛操作放入了BFS的框架中, 主要是使得询问顺序合理, 而这种询问顺序是通用的, 与"最短路"并不是特殊匹配的.因此在这道题中尽管是为了找正环 or 最长路, 也是放在了SFPA的框架下.
啰嗦结束~
#include <cstdio>
#include <queue>
#include <cstring>
const int MAXN=110;
using namespace std;
int n;
int weight[MAXN];
int power[MAXN];
int _count[MAXN];//记录某点的入队列次数
bool map[MAXN][MAXN];
bool reach[MAXN][MAXN];//floyd判断任何两点是否可达 void Floyd(){
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
reach[i][j]=(reach[i][j]
||(reach[i][k]&&reach[k][j]));
}
}
}
} bool SPFA(int now){///求最长路.和求最短路的核心完全不同.只是借助了SPFA对图广搜的流程,判断正环并且避免负环
queue<int>Q;
Q.push(now);
memset(power,0,sizeof(power));
memset(_count,0,sizeof(_count));
power[1]=100;
while(!Q.empty()){
int now=Q.front();
Q.pop();
_count[now]++;///统计该点入队次数
if(_count[now]>=n)return reach[now][n];//如果某个点的次数超过n次,那么说明存在正环,此时只要判断这点到n点是否可达就行了
for(int next=1;next<=n;next++){
if(map[now][next]&&power[now]+weight[next]>power[next]){
///第一次进入时,只要不死都可以进入.第二次进入该店则必有环,那么保证不进入负环或0环
Q.push(next);
power[next]=power[now]+weight[next];
}
}
}
return power[n]>0;
} int main(){
while(~scanf("%d",&n)&&n!=-1){
memset(map,false,sizeof(map));
memset(reach,false,sizeof(reach));
for(int i=1;i<=n;i++){
int num;
scanf("%d%d",&weight[i],&num);
for(int j=1;j<=num;j++){
int k;
scanf("%d",&k);
map[i][k]=true;///邻接矩阵
reach[i][k]=true;///bool可达矩阵
}
}
Floyd();
if(!reach[1][n]){
printf("hopeless\n");
}else {
if(SPFA(1)){
printf("winnable\n");
}else
printf("hopeless\n");
}
}
return 0;
}
[HDU 1317]XYZZY[SPFA变形][最长路]的更多相关文章
- XYZZY(spfa求最长路)
http://acm.hdu.edu.cn/showproblem.php?pid=1317 XYZZY Time Limit: 2000/1000 MS (Java/Others) Memor ...
- HDU - 6201 transaction transaction transaction(spfa求最长路)
题意:有n个点,n-1条边的无向图,已知每个点书的售价,以及在边上行走的路费,问任选两个点作为起点和终点,能获得的最大利益是多少. 分析: 1.从某个结点出发,首先需要在该结点a花费price[a]买 ...
- spfa求最长路
http://poj.org/problem?id=1932 spfa求最长路,判断dist[n] > 0,需要注意的是有正环存在,如果有环存在,那么就要判断这个环上的某一点是否能够到达n点,如 ...
- POJ 3126 --Father Christmas flymouse【scc缩点构图 && SPFA求最长路】
Father Christmas flymouse Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 3007 Accep ...
- BZOJ 2019 [Usaco2009 Nov]找工作:spfa【最长路】【判正环】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2019 题意: 奶牛们没钱了,正在找工作.农夫约翰知道后,希望奶牛们四处转转,碰碰运气. 而 ...
- POJ 3592--Instantaneous Transference【SCC缩点新建图 && SPFA求最长路 && 经典】
Instantaneous Transference Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 6177 Accep ...
- 洛谷 P3627 [APIO2009]抢掠计划 Tarjan缩点+Spfa求最长路
题目地址:https://www.luogu.com.cn/problem/P3627 第一次寒假训练的结测题,思路本身不难,但对于我这个码力蒟蒻来说实现难度不小-考试时肛了将近两个半小时才刚肛出来. ...
- spfa+floyed+最长路+差分约束系统(F - XYZZY POJ - 1932)(题目起这么长感觉有点慌--)
题目链接:https://cn.vjudge.net/contest/276233#problem/F 题目大意:给你n个房子能到达的地方,然后每进入一个房子,会消耗一定的生命值(有可能是负),问你一 ...
- hdu 1534(差分约束+spfa求最长路)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1534 思路:设s[i]表示工作i的开始时间,v[i]表示需要工作的时间,则完成时间为s[i]+v[i] ...
随机推荐
- Android调用系统邮件类应用的正确实现方法
Android应用开发中,很多情况下免不了要调用手机上的邮件类应用,实现邮件发送的功能,这一般是通过调用系统已有的Intent来实现的.看到网上很多邮件发送都是调用action为android.con ...
- 快速构建AdapterView的Adapter--ingeniousadapter
项目地址:ingeniousadapter 前面的话:本项目的原型是QuickAdapter,它们的思路基本一致,但本项目的优势在于: 支持AdapterView存在多个layout类型 可配置图片加 ...
- Oracle用户解锁的三种办法及默认的用户与密码
ORA-28000: the account is locked-的解决办法 2009-11-11 18:51 ORA-28000: the account is locked 第1步:使用PL/SQ ...
- (转)SQL Server2005 异常处理机制(Begin try Begin Catch)
begin try --SQL end trybegin catch --sql (处理出错动作) end catch我们将可能会出错的sql 写在begin try...end try 之间,若出 ...
- ASP.NET批量下载服务器端指定目录文件
//遍历服务器指定文件夹下的所有文件 string path = "uploads/Image/"; string serverPath = Server.MapPath(path ...
- 无法显示TabHost的setIndicator设置的图片的问题解决办法
本想做一个 带有图片的 分页显示的demo 但是 自己的代码写的也木有问题 ,所以只有mainifest 有问题了 主要是用到了 Tabhost <TabHost xmlns:android= ...
- C# 如何获取错误所在行数
两种方法,一种是利用error.StackTrace,另外一种是try-catch找到错误行数,具体如下: 一.error.StackTrace代码 int i = ex.StackTrace.Ind ...
- poj1915 BFS
D - 广搜 基础 Crawling in process... Crawling failed Time Limit:1000MS Memory Limit:30000KB 64bi ...
- JAVA $ JSP
1. java中数据类型分为两种 基本数据类型:数值型,字符型,布尔型 引用数据类型:类,接口,数组 基本数据类型所占空间固定,有别与C++,java中没有无符号数byte:1字节short: ...
- css3之gradient
radial-gradient The CSS radial-gradient() function creates an <image> which represents a gradi ...