vijos1027-spfa关键路径-休息中的阿呆
https://vijos.org/p/1027
给定一个有向图,n个顶点,m个边。每个边有时间作为边权,问从1到n,最少花费多少时间可以把真个图都过一遍(把每个顶点都过一遍)。并且输出所有可能经过的点(用最少时间t走的所有可能经过的点)
思路:spfa改下方向就好了,把d数组改成无穷小,关键路径的输出我是用一个vector存的。当进行松弛操作的时候,如果成功就改。
两种输出关键路径的方法。
坑点:题目中说所有可能的点,意思是如果有两条同样长的点,那么要一起输出,最好的方法是erase和unique了。
我开始以为只要进行过松弛操作,只要把进行过松驰过操作的所有点(to和u都记录,)通过去重就可以得到答案,但是其实不然,因为最长(短)路一定松驰,但是松驰不一定是最长(短)路
见下图,红色的区域发生过松弛操作,但是一定不可能在最短路中
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+4;
vector<pair<int,int> >g[maxn];
int d[maxn];
bool vis[maxn];
vector<int>kk[maxn];
int m;
int mp[maxn][maxn];
vector<int>w;
void dfs(int s,vector<int>q,int v){if(!s){for(int i=0;i<q.size();i++){w.push_back(q[i]);}return;}for(int i=1;i<=m;i++){vector<int>p(q.begin(),q.end());if(d[i]==(s-mp[v][i])&&mp[v][i]){p.push_back(i);dfs(d[i],p,i);}}return;
}
void spfa(){queue<int>q;memset(vis,false,sizeof(vis));memset(d,-0x3f3f3f3f,sizeof(d));for(int i=0;i<maxn;i++)kk[i].clear();q.push(1);vis[1]=true;d[1]=0;while(!q.empty()){int u=q.front();q.pop();vis[u]=false;for(int i=0;i<g[u].size();i++){int to=g[u][i].first;int cost=g[u][i].second;if(d[to]<d[u]+cost){d[to]=d[u]+cost;if(!vis[to]){q.push(to);vis[to]=true;}}else if(d[to]==d[u]+cost){for(int x=0;x<kk[u].size();x++){kk[to].push_back(kk[u][x]);}kk[to].push_back(u);}}}int s=d[m+1];printf("%d\n",s);vector<int>ss;ss.clear();w.clear();dfs(s,ss,m+1);w.push_back(m+1);sort(w.begin(),w.end());w.erase(unique(w.begin(),w.end()),w.end());for(int i=0;i<w.size();i++){if(!i)printf("%d",w[i]);elseprintf(" %d",w[i]);}printf("\n");
}
int main()
{ int n,a,b,c;scanf("%d%d",&m,&n);for(int i=0;i<n;i++){scanf("%d%d%d",&a,&b,&c);g[a].push_back(make_pair(b,c));mp[a][b]=c;mp[b][a]=c;}spfa();return 0;
}
第一个代码还是有点麻烦,得用邻接矩阵(如果存图也用邻接矩阵就没那么麻烦了)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+4;
vector<pair<int,int> >g[maxn];
int d[maxn];
bool vis[maxn];
vector<int>kk[maxn];
int m;
void spfa(){queue<int>q;memset(vis,false,sizeof(vis));memset(d,-0x3f3f3f3f,sizeof(d));for(int i=0;i<maxn;i++)kk[i].clear();q.push(1);vis[1]=true;d[1]=0;while(!q.empty()){int u=q.front();q.pop();vis[u]=false;for(int i=0;i<g[u].size();i++){int to=g[u][i].first;int cost=g[u][i].second;if(d[to]<d[u]+cost){d[to]=d[u]+cost;kk[to].clear();for(int x=0;x<kk[u].size();x++){kk[to].push_back(kk[u][x]);}kk[to].push_back(u);if(!vis[to]){q.push(to);vis[to]=true;}}else if(d[to]==d[u]+cost){for(int x=0;x<kk[u].size();x++){kk[to].push_back(kk[u][x]);}kk[to].push_back(u);}}}//for(int i=1;i<=m+1;i++)//printf("**%d\n",d[i]);sort(kk[m+1].begin(),kk[m+1].end());kk[m+1].erase(unique(kk[m+1].begin(),kk[m+1].end()),kk[m+1].end());printf("%d\n",d[m+1]);for(int i=0;i<kk[m+1].size();i++){if(!i)printf("%d",kk[m+1][0]);elseprintf(" %d",kk[m+1][i]);}printf(" %d",m+1);printf("\n");
}
int main()
{ int n,a,b,c;scanf("%d%d",&m,&n);for(int i=0;i<n;i++){scanf("%d%d%d",&a,&b,&c);g[a].push_back(make_pair(b,c));}//puts("!!!");spfa();return 0;
}
vijos1027-spfa关键路径-休息中的阿呆相关推荐
- P1476 休息中的小呆
P1476 休息中的小呆 题目描述 当大家在考场中接受考验(折磨?)的时候,小呆正在悠闲(欠扁)地玩一个叫"最初梦想"的游戏.游戏描述的是一个叫pass的有志少年在不同的时空穿越对 ...
- 洛谷——P1476 休息中的小呆
P1476 休息中的小呆 题目描述 当大家在考场中接受考验(折磨?)的时候,小呆正在悠闲(欠扁)地玩一个叫"最初梦想"的游戏.游戏描述的是一个叫pass的有志少年在不同的时空穿越对 ...
- ~~spfa判断图中是否存在负环
时间复杂度是 O(nm), n 表示点数,m 表示边数 int n; // 总点数 int h[N], w[N], e[N], ne[N], idx; // 邻接表存储所有边 int dist[N], ...
- 1月13日 :大饼上涨暂时告一段落,中途休息中
一波小上涨完美跟上,可惜错过了最佳的出场位置,让人很难受,不过话说回来,留得青山在不怕没柴烧,我现在不怕踏空,就怕一激动脑袋一热又冲进去出现大幅亏损,当然我也希望读文章的你一样,错过不可怕就怕犯错,还 ...
- 关键路径算法中的etv和ltv的理解
etv和ltv的定义 etv:事件的最早发生时间 ltv:事件的最晚发生时间 (再晚会耽误工期) 关键路径是源点到汇点权值最大的一条路径,这条路径决定了整个工期.关键路径上的关键活动的最早开始的时间和 ...
- 脑科学研究:对于学习来说,休息可能与练习同样重要...
来源:神经科技 近日,在针对健康志愿者的的一项研究中,美国国立卫生研究院(NIH)的研究人员发现,大脑可能会通过短暂的休息来巩固我们几秒钟前刚练习过的新技能的记忆.该研究结果强调了早期休息在学习中可能 ...
- 1230: 最小花费(spfa)
1230: 最小花费 时间限制: 1 Sec 内存限制: 128 MB 题目描述 在n个人中,某些人的银行账号之间可以互相转账.这些人之间转账的手续费各不相同.给定这些人之间转账时需要从转账金额里扣除 ...
- 插入脚注把脚注标注删掉_地狱司机不应该只是英国电影历史数据中的脚注,这说明了为什么...
插入脚注把脚注标注删掉 Cowritten by Andie Yam 由安迪(Andie Yam)撰写 Hell Drivers", 1957地狱司机 >电影海报 Data visua ...
- ACM算法--spfa算法--最短路算法
求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm. SPFA算法是西南交通大学段凡丁于1994年发表的. 从名字我们就可以看出,这种算 ...
最新文章
- python之路-day11-迭代器闭包
- 使用Process Explorer查看托管进程的性能记数器
- 如何轻松愉快地理解条件随机场
- 【Vegas原创】安装rhel6.2,不能进图形化界面的终极解决方法
- Rancher通过Aliyun-slb服务对接阿里云SLB教程
- 【C++】函数 指针类型参数 与 引用类型参数 对比 ( 修改外部变量需要传入的参数要求 | 参数作返回值 )
- 客户端,服务器,天气预报
- Pgbouncer 介绍
- [导入]ASP.NET MVC框架开发系列课程(1):MVC模式与ASP.NET MVC框架概述.zip(8.80 MB)
- 系统架构----(1) 负载均衡
- 测试点击屏幕次数的软件_软件测试工程师面试如何回答登录功能怎么进行测试?...
- python按键退出循环_Python的for循环退出
- 京香julia_百度百科
- pta——特立独行的幸福
- speedoffice(Excel)图片上怎么添加文字
- 动态调试之——x64dbg的使用
- 2022-2028年中国危化品运输行业市场深度分析及投资规模预测报告
- 爬虫初学——爬取京东商品的评论(一)
- 乔布斯的斯坦福演讲(双语)
- ubuntu16.04登录界面输入用户名密码后又回到登录界面