(spfa记录路径)hdu1595+hdu3986
来源:互联网 发布:centos搭建vpn网速慢 编辑:程序博客网 时间:2024/04/20 20:20
题目大意:
其实这两道题大体意思是相同的,就是给你一个图,给定起点和终点,问你在可以毁坏一条路的情况下,从起点到终点的最短路的最远距离。
解题思路
可以看出如果破坏的路不是最短路中的一条,那么实际上不会改变最远距离(因为都是最短路那么长)。所以我们要得到最大答案那么一定是想办法破坏最短路上的边。所以这里枚举破坏最短路上的边即可。
这两道题不同的地方是是前者没有重边,所以我选择通过记录前驱点来记录路径。而后者有可能有重边,所以只能通过记录边的下标来记录路径。
代码hdu1595:
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<string>#include<vector>#include<stack>#include<bitset>#include<cstdlib>#include<cmath>#include<set>#include<list>#include<deque>#include<map>#include<queue>using namespace std;typedef long long ll;const double PI = acos(-1.0);const double eps = 1e-6;const int INF = 0x3f3f3f3f;const int maxn = 1234;int T,n,m,tot;int ans,once;int vis[maxn];int head[maxn];int dis[maxn];int path[maxn];struct EDGE{ int to; int w; int next;}edge[maxn*maxn/2];void init(){ once=1; tot=0; memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); memset(path,0,sizeof(path));}void add_edge(int u,int v,int w){ edge[tot].to=v; edge[tot].w=w; edge[tot].next=head[u]; head[u]=tot++;}int spfa(){ memset(dis,INF,sizeof(dis)); queue<int>q; q.push(1); vis[1]=1; dis[1]=0; path[1]=0; while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; int w=edge[i].w; if(w+dis[u]<dis[v]) { if(once) path[v]=u; dis[v]=dis[u]+w; if(vis[v]==0) { q.push(v); vis[v]=1; } } } } return dis[n];}void print_path(int k){ if(path[k]) print_path(path[k]); printf("%d ",k);}int main(){ while(scanf("%d%d",&n,&m)!=EOF) { init(); for(int i=0;i<m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); add_edge(a,b,c); add_edge(b,a,c); } ans=spfa(); once=0; //枚举删除最短路上的路,求最长结果 int k=n; while(path[k]) { int pos1,pos2; int val; //删双向边 for(int i=head[k];i!=-1;i=edge[i].next) { if(edge[i].to==path[k]) { pos1=i; val=edge[i].w; edge[i].w=INF; break; } } for(int i=head[path[k]];i!=-1;i=edge[i].next) { if(edge[i].to==k) { pos2=i; edge[i].w=INF; break; } } ans=max(ans,spfa()); //恢复边 edge[pos1].w=val; edge[pos2].w=val; k=path[k]; } printf("%d\n",ans); } return 0;}
代码hdu3986:
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<string>#include<vector>#include<stack>#include<bitset>#include<cstdlib>#include<cmath>#include<set>#include<list>#include<deque>#include<map>#include<queue>using namespace std;typedef long long ll;const double PI = acos(-1.0);const double eps = 1e-6;const int INF = 0x3f3f3f3f;const int maxn = 1234;int T,n,m,tot;int ans,once;int vis[maxn];int vis_edge[maxn*maxn/2];int head[maxn];int dis[maxn];int path[maxn];struct EDGE{ int from; int to; int w; int next;}edge[maxn*maxn/2];void init(){ once=1; tot=0; memset(head,-1,sizeof(head)); memset(vis_edge,0,sizeof(vis_edge)); memset(vis,0,sizeof(vis)); memset(path,-1,sizeof(path));}void add_edge(int u,int v,int w){ edge[tot].from=u; edge[tot].to=v; edge[tot].w=w; edge[tot].next=head[u]; head[u]=tot++;}int spfa(){ memset(dis,INF,sizeof(dis)); queue<int>q; q.push(1); vis[1]=1; dis[1]=0; while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i!=-1;i=edge[i].next) { if(vis_edge[i]==1) continue; int v=edge[i].to; int w=edge[i].w; if(w+dis[u]<dis[v]) { if(once) path[v]=i; dis[v]=dis[u]+w; if(vis[v]==0) { q.push(v); vis[v]=1; } } } } return dis[n];}int main(){ scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); init(); for(int i=0;i<m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); add_edge(a,b,c); add_edge(b,a,c); } ans=spfa(); once=0; int k=n; while(path[k]!=-1) { if(ans>=INF) break; vis_edge[path[k]]=vis_edge[path[k]+1]=1; ans=max(ans,spfa()); vis_edge[path[k]]=vis_edge[path[k]+1]=0; k=edge[path[k]].from; } if(ans>=INF) printf("-1\n"); else printf("%d\n",ans); } return 0;}
阅读全文
0 0
- (spfa记录路径)hdu1595+hdu3986
- HDU1595:find the longest of the shortest(spfa+记录路径)
- HDU3986(Harry Potter and the Final Battle)-枚举最短路径+SPFA
- spfa+记录路径模板
- hdu3986
- hdu3986
- HDU3986
- Dijkstra?+spfa+路径的记录
- HDU2433Travel(SPFA+记录路径优化)
- POJ-2457 SPFA+路径记录
- hdu1595 find the longest of the shortest (dijkstra+记录路径)
- HDU1595 find the longest of the shortest(dijk+路径记录+枚举)
- hdu1595(枚举+最短路,Dijkstra/SPFA)
- hdu1595
- HDU1595
- HDU1595
- hdu3986 spfa + 枚举最短路上的边
- 【最短路】poj2457 SPFA+记录路径
- VBA实现EXCEL某一列的部分数据和等于指定值
- Hadoop安装教程_单机/伪分布式配置_Hadoop2.6.0/Ubuntu14.04
- 矩阵的转置
- BatchNorm层分析
- 哪些习惯会使女生越来越漂亮!
- (spfa记录路径)hdu1595+hdu3986
- 数组循环左移
- Hadoop启动dfs时报错Incorrect configuration: namenode address dfs.namenode.servicerpc-address or dfs.namen
- 关于requests模拟登录需要切换账号的学习笔记
- Activity 与 Fragment 三种交互方式
- C# Serializable标签 和序列化
- [js高手之路]设计模式系列课程-设计一个模块化扩展功能(define)和使用(use)库
- oracle重启后,启动监听出现Instance "PLSExtProc", status UNKNOWN
- 入秋这么穿,没人比你更优雅