ural 1930. Ivan's Car
2015-08-26 00:14
519 查看
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1930
题意描述:给定n个城镇以及m条道路,每条道路连接两个城镇,道路有上下两种状态,求起点到终点需要的最少转换状态次数;
思路大致是两种方向分开考虑,更新一个点的状态时引入方向因素;
struct共有两种:Node城镇,里面包含上下两种状态的道路指向的城镇编号,以及按各种状态到达此节点需要转换状态的次数;
Event更新信号,包含要更新的节点编号、更新方向、和最新距离(用于后期检测);
大致步骤:起点节点的距离设置0,构造Event更新信号压入优先队列;
每次取队列里距离最小的Event更新信号,用于双向更新邻接节点,有更新则该邻接节点构造更新信号入队;
队空时退出循环,输出结果;
这次代码很繁杂很凌乱,想了很久,思路不是很直观清晰,甚至用的算法都不是熟知的一些经典算法,而是憋了许久才出来的模型;
放上来只是为了纪念在这道题上流过的汗水,请各位路过的大神批评指正;
上AC代码:
题意描述:给定n个城镇以及m条道路,每条道路连接两个城镇,道路有上下两种状态,求起点到终点需要的最少转换状态次数;
思路大致是两种方向分开考虑,更新一个点的状态时引入方向因素;
struct共有两种:Node城镇,里面包含上下两种状态的道路指向的城镇编号,以及按各种状态到达此节点需要转换状态的次数;
Event更新信号,包含要更新的节点编号、更新方向、和最新距离(用于后期检测);
大致步骤:起点节点的距离设置0,构造Event更新信号压入优先队列;
每次取队列里距离最小的Event更新信号,用于双向更新邻接节点,有更新则该邻接节点构造更新信号入队;
队空时退出循环,输出结果;
这次代码很繁杂很凌乱,想了很久,思路不是很直观清晰,甚至用的算法都不是熟知的一些经典算法,而是憋了许久才出来的模型;
放上来只是为了纪念在这道题上流过的汗水,请各位路过的大神批评指正;
上AC代码:
//#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <stdio.h> #include <string> #include <algorithm> #include <vector> #include <queue> #include <cmath> #include <map> using namespace std; const int NAL = 9999999; // 不可达距离 const int UP = 0; const int DOWN = 1; struct Node{ // 城镇节点,存储上下双方向邻接城镇和双方向距离 vector<int>town[2]; int dis[2]; Node() { dis[0] = dis[1] = NAL; town[0].clear(); town[1].clear(); } }; struct Event{ // 更新信号,存储虚更新的节点编号、有效方向和入队时距离 int index; int dire; int dis; bool operator<(Event a)const{ return dis>a.dis; } }; void func(){ int n, m; scanf("%d%d", &n, &m); vector<Node>v(n); int src, tar; for (int i = 0; i < m; i++){ scanf("%d%d", &src, &tar); src--; tar--; v[src].town[0].push_back(tar); v[tar].town[1].push_back(src); } scanf("%d%d", &src, &tar); src--; tar--; v[src].dis[0] = v[src].dis[1] = 0; Event e; e.index = src; e.dire = UP; e.dis = 0; priority_queue<Event>q; q.push(e); e.dire = DOWN; q.push(e); // 压入src节点的双方向更新信号 while (!q.empty()){ e = q.top(); q.pop(); int dire = e.dire; int dis = e.dis; src = e.index; if (v[src].dis[dire] < dis)continue; // 证明该距离再次被其它节点更新 dis = v[src].dis[dire]; //if (src == tar)break; vector<int> &vSrc = v[src].town[dire]; //更新同方向节点信息 for (size_t i = 0; i < vSrc.size(); i++){ int tmpTar = vSrc[i]; if (v[tmpTar].dis[dire] == NAL || v[tmpTar].dis[dire] > dis){ v[tmpTar].dis[dire] = dis; e.index = tmpTar; q.push(e); } } dire = (dire + 1) & 1; dis++; vector<int>&vTar = v[src].town[dire]; // 更新反方向节点信息 for (size_t i = 0; i < vTar.size(); i++){ int tmpTar = vTar[i]; if (v[tmpTar].dis[dire] == NAL || v[tmpTar].dis[dire]>dis){ v[tmpTar].dis[dire] = dis; e.index = tmpTar; e.dis = dis; e.dire = dire; q.push(e); } } } int ans = v[tar].dis[0]; if (ans > v[tar].dis[1])ans = v[tar].dis[1]; printf("%d\n", ans); } int main(){ //freopen("out.txt", "w", stdout); //freopen("in.txt", "r", stdin); func(); }
相关文章推荐
- 如何从Apache官网下载windows版apache服务器
- 常用端口
- rpm -e yum 之后
- Java四种引用类型
- Java四种引用类型
- UCI提供给shell和lua使用的配置接口
- Java四种引用类型
- 树与二叉树的转换
- pthread_cond_wait和pthread_cond_signal以及互斥变量的使用情况
- 22.2015.08.18第二十三课mvc1,2(mvc环境搭建)
- 关于位操作的知识点
- 题目:买卖股票的最佳时机
- 2015 Multi-University Training Contest 10(hdu 5406 - hdu 5416)
- cocoapods应用第一部分-xcode创建.framework相关
- mysql文档摘要续4
- 无缝滚动效果
- Android Animation动画详解(二): 组合动画特效
- android 支付简谈
- Android Animation动画详解(二): 组合动画特效
- hdu 1162 Eddy's picture