[HDOJ5521]Meeting(最短路)
2016-04-25 15:13
337 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5521
给n个点,m个块。块内点到点之间话费的时间ti。两个人分别从点1和点n出发,问两人是否可以相遇,并求出相遇最短时间和路径,路径按照字典序输出。
这题的难点在于处理块内的点到块外点的关系。我们可以添加一个“集合点”,此点到集合内各点距离为w,点到此集合的距离为0建图。
从1和n分别做一次最短路,找到每一个距离最长的点(即为相遇点),记下长度再枚举两个结果,看一共多少个相遇点
给n个点,m个块。块内点到点之间话费的时间ti。两个人分别从点1和点n出发,问两人是否可以相遇,并求出相遇最短时间和路径,路径按照字典序输出。
这题的难点在于处理块内的点到块外点的关系。我们可以添加一个“集合点”,此点到集合内各点距离为w,点到此集合的距离为0建图。
从1和n分别做一次最短路,找到每一个距离最长的点(即为相遇点),记下长度再枚举两个结果,看一共多少个相遇点
#include <algorithm> #include <iostream> #include <iomanip> #include <cstring> #include <climits> #include <complex> #include <fstream> #include <cassert> #include <cstdio> #include <bitset> #include <vector> #include <deque> #include <queue> #include <stack> #include <ctime> #include <set> #include <map> #include <cmath> using namespace std; typedef long long ll; typedef pair<int, int> pii; typedef struct E { int w; int v; E() {} E(int vv, int ww) : v(vv), w(ww) {} }E; const int inf = 0x7f7f7f7f; const int maxn = 200010; priority_queue<pii, vector<pii>, greater<pii> > pq; vector<E> e[maxn]; vector<int> path; ll d[3][maxn]; int n, m, u, v, w, k; template<int cho> void dijkstra(int s) { memset(d[cho], inf, sizeof(d[cho])); while(!pq.empty()) pq.pop(); d[cho][s] = 0; pq.push(pii(0, s)); while(!pq.empty()) { pii cur = pq.top(); pq.pop(); w = cur.first; v = cur.second; if(d[cho][v] < w) continue; for(int i = 0; i < e[v].size(); i++) { if(d[cho][e[v][i].v] > d[cho][v] + e[v][i].w) { d[cho][e[v][i].v] = d[cho][v] + e[v][i].w; pq.push(pii(d[cho][e[v][i].v], e[v][i].v)); } } } } inline bool scan_d(int &num) { char in;bool IsN=false; in=getchar(); if(in==EOF) return false; while(in!='-'&&(in<'0'||in>'9')) in=getchar(); if(in=='-'){ IsN=true;num=0;} else num=in-'0'; while(in=getchar(),in>='0'&&in<='9'){ num*=10,num+=in-'0'; } if(IsN) num=-num; return true; } int main() { // freopen("in", "r", stdin); int T, _ = 1; scan_d(T); while(T--) { for(int i = 0; i < maxn; i++) e[i].clear(); path.clear(); scan_d(n); scan_d(m); for(int i = 1; i <= m; i++) { scan_d(w); scan_d(k); while(k--) { scanf("%d", &v); e[n+i].push_back(E(v, w)); e[v].push_back(E(n+i, 0)); } } dijkstra<0>(1); dijkstra<1>(n); ll cur = inf; for(int i = 1; i <= n; i++) { cur = min(cur, max(d[0][i], d[1][i])); } for(int i = 1; i <= n; i++) { if(cur == max(d[0][i], d[1][i])) { path.push_back(i); } } printf("Case #%d: ", _++); if(cur == inf) { printf("Evil John\n"); continue; } printf("%I64d\n", cur); for(int i = 0; i < path.size(); i++) { printf("%d", path[i]); if(i == path.size() - 1) printf("\n"); else printf(" "); } } return 0; }
相关文章推荐
- 自动设置IP地址的BAT
- JVM字节指令详解
- Zabbix 监控Redis
- 一个话务员给n个人打了n次电话,但是话务员记性不好,没记得给谁打过,没接到电话的人占总人数的多少
- 网易云音乐App(iOS)分析
- 深入挖掘document.getElementsByTagName()方法的返回值
- java连接solr并建立索引
- jq中的移除事件
- MySQL中concat函数(连接字符串)
- [DllImport("kernel32.dll")]使用
- 手机访问网站如何自动跳转到手机版本自动转到手机网站
- Require.js的用法
- JQuery语法、选择器、事件器
- Java泛型-类型擦除
- RESideMenu左右半侧滑的功能实现,主视图会和状态栏(StatusBar)不会随着一起滑动
- 按钮宽度和高度固定,字体大小根据字数自适应用的javascript实现
- vtk实战(五)—格式转换
- Java操作Ini文件
- 【codeforces 1A】Theatre Square——数学,水
- [Java]工厂设计模式