哈理工oj 1339-Touring解题报告
2012-04-11 21:10
357 查看
链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1339
这道题是用dijkstra求最短路径,然后找出三个点到一个点的最小路径总和,数据量很大,所以一般朴素的dijkstra会超时,所以采用堆优化,纠结啊,调了一天,最后才想明白怎么处理不可达的情况,这是很多网上给出的堆优化难以解决的问题,也算是学了些东西了。其实学ACM重要的就是这种耐心和灵感。
View Code
这道题是用dijkstra求最短路径,然后找出三个点到一个点的最小路径总和,数据量很大,所以一般朴素的dijkstra会超时,所以采用堆优化,纠结啊,调了一天,最后才想明白怎么处理不可达的情况,这是很多网上给出的堆优化难以解决的问题,也算是学了些东西了。其实学ACM重要的就是这种耐心和灵感。
View Code
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #define N 5005 using namespace std; const int NoEdge=0xfffffff; int size,n; struct node { int n; int v; }; node heap[2*N]; int ph ; bool used ; vector<node> g ; int da ,db ,dc ; int parent(int i) { return i>>1; } int left(int i) { return i<<1; } int right(int i) { return (i<<1)+1; } void MIN_HEAPIFY(int i)//最小根堆 { node temp; int small=i; if(left(i)<=size&&heap[left(i)].v<heap[i].v) small=left(i); if(right(i)<=size&&heap[right(i)].v<heap[small].v) small=right(i); if(small!=i) { ph[heap[small].n]=i; ph[heap[i].n]=small; temp=heap[i]; heap[i]=heap[small]; heap[small]=temp; MIN_HEAPIFY(small); } } node extract_min()//取根节点 { node min=heap[1]; heap[1]=heap[size--]; ph[heap[1].n]=1; MIN_HEAPIFY(1); return min; } void decrease(int i,int k)//更新节点的权值 { heap[i].v=k; int j; while(i>1&&heap[i].v<heap[parent(i)].v) { ph[heap[parent(i)].n]=i; ph[heap[i].n]=parent(i); node temp; temp=heap[i]; heap[i]=heap[parent(i)]; heap[parent(i)]=temp; i=parent(i); } } bool empty() { return size==0; } void dijkstra(int s,int *d) { int i,j; for(i=1;i<=n;i++) { heap[i].n=i; heap[i].v=NoEdge; ph[i]=i; } decrease(s,0); node min; while(!empty()) { min=extract_min(); d[min.n]=min.v; used[min.n]=true;//已经发现要记住 int num=g[min.n].size(); for(i=0;i<num;i++) { if(!used[g[min.n][i].n]&&heap[ph[g[min.n][i].n]].v>min.v+g[min.n][i].v) { decrease(ph[g[min.n][i].n],min.v+g[min.n][i].v); } } } } int main() { int i,j; int s,t; int dis; int a,b,c; int m; node temp; int icase=1; while(scanf("%d%d",&n,&m)!=EOF) { memset(used,0,sizeof(used)); for(i=1;i<=n;i++) g[i].clear(); scanf("%d%d%d",&a,&b,&c); size=n; for(i=1;i<=n;i++) { da[i]=db[i]=dc[i]=NoEdge; } for(i=0;i<m;i++) { scanf("%d%d%d",&s,&t,&dis); temp.n=t; temp.v=dis; g[s].push_back(temp); temp.n=s; g[t].push_back(temp); } printf("Scenario #%d\n",icase++); dijkstra(a,da); if(da[b]==NoEdge||da[c]==NoEdge) { printf("Can not reah!\n\n"); continue; } size=n; memset(used,0,sizeof(used)); dijkstra(b,db); size=n; memset(used,0,sizeof(used)); dijkstra(c,dc); int max=NoEdge; for(i=1;i<=n;i++) { if(da[i]!=NoEdge&&dc[i]+da[i]+db[i]<max)//寻找最小的总权值 { max=dc[i]+da[i]+db[i]; } } printf("%d\n\n",max); } return 0; }
相关文章推荐
- 哈理工oj 1116 解题报告 动态规划-依次输出最长公共子序列的位置
- 哈理工oj 1385-Leyni, LOLI and Toasts II解题报告-多重背包的二进制解法
- 哈理工OJ1671解题报告
- 哈理工oj 1392-Leyni, LOLI and Houses解题报告
- 哈理工oj 1328-相等的最小公倍数解题报告
- 哈理工oj 1353-LCM与数对解题报告
- 哈理工oj 1360-Leyni的国家III解题报告
- 哈理工oj 1250-Minimum Inversion Number解题报告
- 哈理工oj 1306-再遇攻击解题报告
- 哈理工oj 1341-Who will be punished解题报告
- 哈理工hrbust OJ 2225 解题报告
- 哈理工OJ 1338-Monkey CC解题报告
- 哈理工oj-1049Jigsaw Puzzle解题报告
- 杭电OJ题 1577 WisKey的眼神 解题报告
- 【九度OJ】题目1047:素数判定 解题报告
- 【九度OJ】题目1076:N的阶乘 解题报告
- 杭电oj--2186解题报告
- 【算法学习笔记】26.扫描维护法 解题报告 SJTU OJ 1133 数星星
- 【算法学习笔记】29.规律题 解题报告 SJTU OJ 1101 SuperXOR
- 九度OJ题目1164:旋转矩阵解题报告