这道题题目真的想吐槽一下...是在机房同学的解释下才看懂的。就是让你求在可以删一条边的情况下,并且删后保证可以到达终点时,求删了后的最大的最短路径。


70分暴力思路:

枚举删边,然后跑一下最短路即可,思路很简单,下面给出70分代码:

#include <bits/stdc++.h>
using namespace std;
vector<pair<int , int> > e[1010];
int n , m , ans;
int dis[1010] , vis[1010] , l[500010] , r[500010];
void work(int uu , int vv){
memset(dis , 127 , sizeof(dis));
memset(vis , 0 , sizeof(vis));
queue<int> q;
dis[1] = 0;
vis[1] = 1;
q.push(1);
while(!q.empty()){
int x = q.front();
q.pop();
vis[x] = 0;
for(int i = 0; i < e[x].size(); i++){
int y = e[x][i].first , w = e[x][i].second;
if((x == uu && y == vv) || (x == vv && y == uu)) continue; //不走这一条路
if(dis[y] > dis[x] + w){
dis[y] = dis[x] + w;
if(!vis[y]){
vis[y] = 1;
q.push(y);
}
}
}
}
ans = max(ans , dis[n]);
}
int main(){
cin >> n >> m;
for(int i = 1; i <= m; i++){
int x , y , z;
cin >> x >> y >> z;
l[i] = x , r[i] = y; //存储每一条边
e[x].push_back(make_pair(y , z));
e[y].push_back(make_pair(x , z));
}
for(int i = 1; i <= m; i++) work(l[i] , r[i]); //删除
cout << ans;
return 0;
}

100分满分思路:

我们先预处理求一遍最短路,当我们开始删边时,如果删的不是最短路径上的边时,那么答案还是原来的最短路,因为我们最短路要用的边一条没变。所以,我们只需要枚举删掉最短路上的边即可,这样答案一定改变,同时注意能达到终点。下面给出满分代码:

#include <bits/stdc++.h>
using namespace std;
vector<pair<int , int> > e[1010];
int n , m , ans;
int dis[1010] , vis[1010] , pre[1010];
void work(int uu , int vv){
for(int i = 1; i <= n; i++) vis[i] = 0 , dis[i] = 0x3ffffff;
queue<int> q;
dis[1] = 0;
vis[1] = 1;
q.push(1);
while(!q.empty()){
int x = q.front();
q.pop();
vis[x] = 0;
for(int i = 0; i < e[x].size(); i++){
int y = e[x][i].first , w = e[x][i].second;
if((x == uu && y == vv) || (x == vv && y == uu)) continue;
if(dis[y] > dis[x] + w){
dis[y] = dis[x] + w;
if(!vis[y]){
vis[y] = 1;
q.push(y);
}
}
}
}
ans = max(ans , dis[n]);
}
void p_work(){
for(int i = 1; i <= n; i++) vis[i] = 0 , dis[i] = 0x3ffffff;
queue<int> q;
dis[1] = 0;
vis[1] = 1;
q.push(1);
while(!q.empty()){
int x = q.front();
q.pop();
vis[x] = 0;
for(int i = 0; i < e[x].size(); i++){
int y = e[x][i].first , w = e[x][i].second;
if(dis[y] > dis[x] + w){
dis[y] = dis[x] + w;
pre[y] = x; //记录前驱
if(!vis[y]){
vis[y] = 1;
q.push(y);
}
}
}
}
ans = max(ans , dis[n]);
}
int main(){
scanf("%d%d" , &n , &m);
for(int i = 1; i <= m; i++){
int x , y , z;
scanf("%d%d%d" , &x , &y , &z);
e[x].push_back(make_pair(y , z));
e[y].push_back(make_pair(x , z));
}
p_work(); //预处理删哪些边
for(int i = n; i; i = pre[i]) work(i , pre[i]);
cout << ans;
return 0;
}

最新文章

  1. linux定时任务的设置 crontab 配置指南
  2. IOS第一天多线程-04GCD通信
  3. 自定义Encoder/Decoder进行对象传递
  4. 简单的下拉刷新以及优化--SwipeRefreshLayout
  5. 1.6建造者模式(生成器模式) Builder
  6. monkey与monkeyrunner的使用
  7. jQuery中ready与load事件的区别
  8. ios 异步多线程 获取数据
  9. [ An Ac a Day ^_^ ][kuangbin带你飞]专题八 生成树 POJ 1679 The Unique MST
  10. linux虚拟机 在install yum时提示无法获得锁 var/lib/dekg/lock时该如何解决?
  11. python 面向对象(五)约束 异常处理 MD5 日志处理
  12. 基于PySpark的网络服务异常检测系统 阶段总结(二)
  13. docker从容器里面拷文件到宿主机或从宿主机拷文件到docker容器里面
  14. LeetCode 81 搜索旋转排序数组II
  15. Java:判断当前操作系统界面采用的主题是windows经典样式还是xp样式
  16. vue 安装sass扩展
  17. (转)javascript方法--bind()
  18. Zuul Timeouts
  19. 为什么 Redis 重启后没有正确恢复之前的内存数据
  20. android 布局的两个属性 dither 和 tileMode

热门文章

  1. Java实现 蓝桥杯 算法训练 Beaver's Calculator
  2. Java实现 LeetCode 566 重塑矩阵(遍历矩阵)
  3. Java实现 蓝桥杯VIP 算法训练 友好数
  4. Java实现 LeetCode 139 单词拆分
  5. Java实现 洛谷 P1980 计数问题
  6. Linux 终止进程
  7. 关于晶体问题TCXO_14.7456MHZ
  8. 温故知新-java虚拟机
  9. 【网页设计】第四周 JavaSript
  10. PAT1040 Longest Symmetric String (25分) 中心扩展法+动态规划