[题目链接](http://acm.hdu.edu.cn/showproblem.php?pid=3499)

刚看见题目,哦?不就是个最短路么,来,跑一下dijkstra记录最长路除个二就完事了 ,但是。。。。。。

走红色的路是最佳方案,但是蓝色路的最短路跟短,我想错了;

不久我又想,把每个边枚举一下,减半一个边,就跑一次dijstra,但是这太慢了,O(m*m*logm)

拜拜了您內

后来看了看网上的大佬,其实也可以枚举嘛,只要每一次枚举都是O(1)。显然需要预处理一下,正线边跑一次,反向边跑一次

这样就可以了

听说还可以分层图,没看懂,猜测了一下原理

就这样了

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
#include<string>
using namespace std;
typedef long long ll;
const int maxn = 5e5 + 100;
const long long INF = 1e12;
struct Node {
ll p, val;
Node(ll a, ll b) :p(a), val(b) {}
};
bool operator <(const Node a, const Node b) {
if (a.val > b.val) return true;
else return false;
}
int n, m;
ll d1[maxn];
ll d2[maxn];
int vis[maxn];
vector<Node>G[maxn];
void insert(int be, int en, int len) {
G[be].push_back(Node(en, len));
return;
}
int dijstra(ll *dis, int be) {
for (int i = 0; i <= n; i++) {
vis[i] = 0;
dis[i] = INF;
}
dis[be] = 0;
priority_queue<Node>que;
que.push(Node(be, 0));
while (!que.empty()) {
Node ans = que.top();
que.pop();
if (vis[ans.p] == 0) {
vis[ans.p] = 1;
for (int i = 0; i < G[ans.p].size(); i++) {
int p = G[ans.p][i].p;
if (!vis[p] && dis[p] > dis[ans.p] + G[ans.p][i].val) {
dis[p] = dis[ans.p] + G[ans.p][i].val;
que.push(Node(p, dis[p]));
}
}
}
}
return 0;
}
map<string, int>ins;
ll be_[maxn];
ll en_[maxn];
ll len_[maxn];
int main() {
while (~scanf("%d %d", &n, &m)) {
ins.clear();//可得记得清空啊
string be, en;
ll len = 0;
int c = 0;
int cnt = 1;
while (m--) {
cin >> be >> en;
scanf("%lld", &len);
if (ins[be] == 0) ins[be] = cnt++;
if (ins[en] == 0) ins[en] = cnt++;
be_[c] = ins[be];
en_[c] = ins[en];
len_[c] = len;
c++;
insert(ins[en], ins[be], len);
}
cin >> be >> en;
if (ins[be] == 0) ins[be] = cnt++;
if (ins[en] == 0) ins[en] = cnt++;
dijstra(d2, ins[en]);
for (int i = 0; i <= n; i++) G[i].clear();
for (int i = 0; i < c; i++) {
insert(be_[i], en_[i], len_[i]);
}
dijstra(d1, ins[be]);
ll ans = d1[ins[en]];
if (ans == INF) {
printf("-1\n");
continue;
}
for (int i = 1; i <= n; i++) {
for (int j = 0; j < G[i].size(); j++) {
ans = min(ans, d1[i] + d2[G[i][j].p] + G[i][j].val / 2);//每个顶点刷出来边试探
}
} printf("%lld\n", ans);
for (int i = 0; i <= n; i++) G[i].clear();
}
return 0;
}

  

最新文章

  1. 深入浅出JS的封装与继承
  2. 【POJ 3241】Object Clustering 曼哈顿距离最小生成树
  3. Node.js基于Express框架搭建一个简单的注册登录Web功能
  4. POJ 3206 最小生成树
  5. contentWindow 和contentDocument区别 及iframe访问
  6. Linux下如何在打开终端的时候自动配置相关环境
  7. UVAlive4287 Proving Equivalences(scc)
  8. convertView
  9. struts2.3.23升级到struts2.3.32
  10. vue-cli 前端开发,后台接口跨域代理调试问题
  11. action之间传参为中文;type=&#39;redirect&#39;和 type=&#39;redirectAction&#39;主要区别
  12. Shiro【授权过滤器、与ehcache整合、验证码、记住我】
  13. python3中用HTMLTestRunner.py报ImportError: No module named &#39;StringIO&#39;解决办法
  14. hive中left/right join on连接中and与where的使用问题
  15. 2018.5.8 python操纵sqlite数据库
  16. python3 requestsGET请求传参
  17. ERP产品销售发货判断库存功能(四十二)
  18. 第一章 CSS基础
  19. P3317 [SDOI2014]重建(Matrix-tree+期望)
  20. ScheduledThreadPoolExecutor

热门文章

  1. 记一次Celery的仇
  2. oracle函数 ROW_NUMBER()
  3. php 正则表达式怎么匹配标签里面的style?
  4. 解决bootStrap selectpicker 下拉栏上方弹出
  5. 梯度优化算法Adam
  6. 系统学习前端之FormData详解
  7. oracle自动选择索引
  8. javascript 容易混淆遗忘的基础知识
  9. H3C DCC概念
  10. React与Vue的相同与不同点