【HDU3873 Invade the Mars】有保护节点的最短路(优先队列+spfa)
2013-05-03 14:04
246 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3873
题目大意:美国佬打算入侵火星,火星上有n个城市,有些城市可能受其他城市保护,如果i城市受j城市保护,那么你必须先攻占j城市才能再攻占i城市,问你攻占城市n的最短时间是多少。
解题思路:开一个优先队列,每次将图中不受保护并的节点加入队列(注意不受保护的节点可能重复入队,所以要做个标记,只处理优先队列中第一个出来的重复节点),spfa()单源最短路进行操作,num[u]表示保护节点u的城市有多少个,当num[u]为0的时候可以把u加入队列。处理受保护的节点v时,disv=max(disu,dis[v]),disu表示达到保护u的最后一个节点的时间,dis[v]表示spfa到达v的最短时间,两者取最大值。
View Code
题目大意:美国佬打算入侵火星,火星上有n个城市,有些城市可能受其他城市保护,如果i城市受j城市保护,那么你必须先攻占j城市才能再攻占i城市,问你攻占城市n的最短时间是多少。
解题思路:开一个优先队列,每次将图中不受保护并的节点加入队列(注意不受保护的节点可能重复入队,所以要做个标记,只处理优先队列中第一个出来的重复节点),spfa()单源最短路进行操作,num[u]表示保护节点u的城市有多少个,当num[u]为0的时候可以把u加入队列。处理受保护的节点v时,disv=max(disu,dis[v]),disu表示达到保护u的最后一个节点的时间,dis[v]表示spfa到达v的最短时间,两者取最大值。
View Code
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> using namespace std; const int maxn=3333; const long long oo=1000000007ll; typedef long long lld; int visit[maxn], num[maxn]; lld dis[maxn]; int n; struct node { int x; lld dis; friend bool operator<(const node &A, const node &B) { return A.dis>B.dis; } }; struct Node { int v, val; Node() {} Node(int v_, int val_) { v=v_, val=val_; } }; vector<Node>vt[maxn]; vector<int>ct[maxn]; void spfa() { for(int i=1; i<=n; i++) dis[i]=oo, visit[i]=0; priority_queue<node>q; node s; s.x=1, s.dis=0; dis[s.x]=0; q.push(s); while(!q.empty()) { int u=q.top().x; lld du=q.top().dis; q.pop(); if(visit[u]) continue; ///访问过的节点就不必在处理了 visit[u]=1; if(u==n) { cout << du <<endl; return ; } for(int i=0; i<vt[u].size(); i++) { s.x=vt[u][i].v, s.dis=du+vt[u][i].val; if(s.dis<dis[s.x]) { dis[s.x]=s.dis; if(!num[s.x]) q.push(s); } } for(int i=0; i<ct[u].size(); i++) { s.x=ct[u][i]; if(visit[s.x]) continue; num[s.x]--; if(!num[s.x]) { s.dis=max(du,dis[s.x]); q.push(s); } } } } int main() { int m, T; cin >> T; while(T--) { scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) vt[i].clear(), ct[i].clear(), num[i]=0; for(int i=0; i<m; i++) { int u, v, val; scanf("%d%d%d",&u,&v,&val); vt[u].push_back(Node(v,val)); } for(int i=1; i<=n; i++) { int x; scanf("%d",&num[i]); for(int j=1; j<=num[i]; j++) { scanf("%d",&x); ct[x].push_back(i); } } spfa(); } return 0; }
相关文章推荐
- hdu3873带节点保护的最短路
- hdu 3873 Invade the Mars 有保护节点的最短路
- HDU 3873 带保护节点的最短路
- hdu 3873(有节点保护的最短路)
- hdu 3873(有节点保护的最短路)
- Web.config 中的 节点设置--灵活运用表单认证中的 deny 与 allow 及保护 .htm 等文件
- 锂电池过充电、过放电、短路保护电路详解
- (阶段三 dijkstra算法温习1.1)HDU 2544 最短路(利用dijkstra算法计算两个节点间的最短路径)
- 怎样保护CDN节点来应对DDOS攻击
- 锂电池过充电、过放电、短路保护电路详解
- Floyd求最短路+输出路径上节点
- 稳压电源 连载14:过载和短路的保护
- 短路保护、过载保护、零压保护的概念
- UVALive 3661 Animal Run(平面图最小割,边为节点+最短路)
- 最短路小结 Floyd + Dijkstra + 带花费 + 字符节点
- (CCF 201403-4)无线网络 最短路变形:节点访问限制 + [SPFA]
- IEC61850变电站通信网络和系统--5功能的通信要求和装置模型_2保护逻辑节点
- HDU 5521 Meeting(虚拟节点+最短路)
- 简单方短路保护法
- 硬件知识--短路保护电路