[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] ...
随机推荐
- Laravel 4 Blade模板引擎
http://my.oschina.net/5say/blog/201290 模板输出 基本输出 1 <!-- app/views/example.blade.php --> 2 < ...
- C++11 多线程 教学(2)
C++11开始支持多线程编程,之前多线程编程都需要系统的支持,在不同的系统下创建线程需要不同的API如pthread_create(),Createthread(),beginthread()等, ...
- Android Notification使用及取消
//发送通知 NotificationManager manger = (NotificationManager) this.getSystemService(NOTIFICATION_SERVICE ...
- 使用DataReader
string sqlStr="select * from tb_news"; SqlCommand myCmd=new SqlCommand(sqlStr,myConn); myC ...
- DTO学习系列之AutoMapper(二)
本篇目录: Flattening-复杂到简单 Projection-简单到复杂 Configuration Validation-配置验证 Lists and Array-集合和数组 Nested m ...
- poj 2479 dp求分段最大和
Maximum sum Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 38079 Accepted: 11904 Des ...
- Linux知识扫盲
1.发现linux中好多软件以d结尾,d代表什么? d 代表 deamon 守护进程守护进程是运行在Linux服务器后台的一种服务程序.现在比较常用 是 service 这个词.它周期性地执行某种任务 ...
- C语言数组作为函数参数
数组可以作为函数的参数使用,进行数据传送. 数组用作函数参数有两种形式,一种是把数组元素(下标变量)作为实参使用:另一种是把数组名作为函数的形参和实参使用. 数组元素作函数实参 数组元素就是下标变量, ...
- [Mugeda HTML5技术教程之16]案例分析:制作跨屏互动游戏
本节我们将要做一个跨屏互动应用的案例分析,该应用时给一家商场做活动使用的,是一个跨屏爱消除游戏.PC端页面显示在连接在PC的大屏幕上,参与活动的玩家可以用自己的手机扫描PC端页面上的二维码,连接成功后 ...
- 解决位于底端Edittext 输入时被软盘遮盖
遇到这种情况我们首先到网上搜一圈,大概情况是需要设置<activity/> android:windowSoftInputMode="adjustResize" ,按照 ...