6-08. 城市间紧急救援
2014-06-16 23:17
274 查看
#include<vector> #include<iostream> using namespace std; const int N=500,INF=1<<30; int n,m,src,dst,pre ,dis ,team ,gather ,used ,path ; struct road{int to,len;road(int a,int b):to(a),len(b){}}; vector<road>adj ; void dijkstra(){ //initialization fill_n(dis,n,INF);dis[src]=0; fill_n(pre,n,-1); path[src]=1,gather[src]=team[src]; while(true){ // find a new city next int next=-1,mmin=INF; for(int i=0;i<n;++i) if(!used[i] && dis[i]<mmin) mmin=dis[next=i]; if(next==-1)break; used[next]=true; // relax the edges starting from next for(auto x:adj[next]){ int to=x.to,len=x.len; if(dis[next]+len<dis[to]){ path[to]=path[next]; pre[to]=next; dis[to]=dis[next]+len; gather[to]=gather[next]+team[to]; }else if(dis[next]+len==dis[to]){ path[to]+=path[next]; if(gather[to]<gather[next]+team[to]){ gather[to]=gather[next]+team[to]; pre[to]=next;}//if }//else if }//for }//while }//dijkstra void printpath(int k){ if(pre[k]!=-1)printpath(pre[k]); static bool first=true; if(first)first=false; else cout<<' '; cout<<k; } int main(){ cin>>n>>m>>src>>dst; for(int i=0;i<n;++i)cin>>team[i]; while(m--){ int a,b,c;cin>>a>>b>>c; adj[a].emplace_back(b,c); adj[b].emplace_back(a,c); } dijkstra(); cout<<path[dst]<<' '<<gather[dst]<<endl; printpath(dst); return 0; }dijkstra算法每个点会收敛一次,每条边会松弛一次,每个点的收敛是一个循环,dis[ ]在每轮迭代前后表示从原点到各点的已知最短距离,pre[ ]表示从原点到个点最短路径上的前一节点,path[ ]表示到每个节点的最优路径的条数,对一条路径<a,b>,松弛它后能得到两种结论:一是通过<a,b>到达b的路径(这条路径之前肯定没检查过,因为每条路径只会被松弛一次)比当前到达b的路径更短,二是它同样短,更短会造成path[b] = path[a],同样短则有path[b]+=path[a],同样短的路径根据其他条件决定哪个是更好的路径。
算法并不是套用在问题上,“定义并使用定义”才是用算法解决问题的思维,尤其是在循环表达式里使用定义,这里对path ,dis ,pre 这几个数组的定义及循环表达式前后的保持是关键。经典的dijkstra算法也只是使用了一个简单的循环表达式而已。就像所有节点最短路径的floyd算法,它的正确性是从DP角度解释的,但硬要从DP角度理解十分困难,但从不变式角度理解就很简单,定义dis[i][j]是当前已知的从i到j的最短路径值,pre[i][j]是i~>j的这条最短路径中j节点的前驱结点,算法保持住了这个性质。这样理解简单很多。
相关文章推荐
- 6-08. 城市间紧急救援(25)--Dijkstra
- PAT 一 城市间紧急救援
- Dijkstra算法-城市间紧急救援
- 城市间紧急救援
- 城市间紧急救援(25 分)
- 城市间紧急救援 ,复杂点的最短路,记录路径,记录最短路个数等
- 城市间紧急救援-多维最短路
- 城市间紧急救援(25 分)
- jquery03-08城市选择案例
- 08-jbpm工作流之Decision流程决策(判断活动执行方向)
- 【面试】Liveramp 面试题 面经 城市问题
- Java基础--->08.判断语句(if、else if、switch、while、do while)。
- UVA 1025 A Spy in the Metro城市里的间谍(dp)
- ip地址查询城市
- 城市交通
- 黑马程序员--08.注解--03【自定义注解】【为注解添加属性】
- ABAP 开发系列(08): SAP Open SQL
- 08-Oracle学习_DML-insert-update-delete
- (ssl1636)城市交通
- 【字符串操作】08.将单词的首字母大写