[HDU 2544] 最短路 spfa写法 + 链式前向星
2016-05-11 10:43
489 查看
spfa是对迪杰斯特拉算法的队列优化,套路大概就是:
让dis[1] 入队, 然后判断队列是否为空;
让它赋给队首, 然后就是一样的循环;
唯一的区别就是这个地方!vis[i] 是拆开放在后面的;
AC代码:
链式前向星写法:
让dis[1] 入队, 然后判断队列是否为空;
让它赋给队首, 然后就是一样的循环;
唯一的区别就是这个地方!vis[i] 是拆开放在后面的;
AC代码:
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <queue> #define ll long long #define inf 9999999 using namespace std ; int dis[2000] , vis[2000] , map[200][2000] , u , v ; void input(); void init(); void spfa(); void output(); int main() { while(scanf("%d%d",&v,&u),v+u) { init(); input(); spfa(); output(); } } void input() { for(int i = 0 ; i < u;i++) { int a , b , len ; scanf("%d%d%d",&a,&b,&len); if(map[a][b] > len) { map[a][b] = map[b][a] = len ; } } } void init() { for(int i = 0 ; i <=v ;i++) { for(int j = 0 ; j<=v;j++) { map[i][j] = inf ; } dis[i] = inf ; vis[i] = 0 ; map[i][i] = 0 ; } } void output() { printf("%d\n",dis[v]); } void spfa() { queue<int>Q; dis[1] = 0 ; Q.push(1); vis[1] = 1 ;//*初始点肯定是会被使用了的 while(!Q.empty()) { int now = Q.front(); Q.pop(); vis[now] = 0 ; //*这个地方是0不是1 ; 因为出队时候这个now还并没有被使用 for(int i = 1 ; i <=v ;i++) { if(dis[i] > dis[now] + map[now][i]) { dis[i] = dis[now] + map[now][i]; if(!vis[i]) { Q.push(i); vis[i] = 1 ;//*使用了后就标记 } } } } }
链式前向星写法:
#include <bits/stdc++.h> #define inf 9999999 using namespace std ; int head[11000] , vis[110] , dis[110] ; struct node { int to ;//*表示第i边的终点 int next;//*表示与i边同起点的下一条边的位置 int val;//*当前边的权值 }edge[11000]; int u , v , ans ;//*u是边,v是点,ans是队位置 void add(int u , int v , int val) { int i , t = 0 ; for(i = head[u] ; i!=-1 ; i = edge[i].next) //*去重 { if(v ==edge[i].to && val >= edge[i].val) { t = 1 ; break; } } if(t==1) return ; edge[ans].to = v ;//*构建无向图 edge[ans].val = val; edge[ans].next = head[u] ; head[u] = ans++; edge[ans].to = u ; edge[ans].val = val; edge[ans].next = head[v]; head[v] = ans++; return ; } void spfa() { queue<int>Q; dis[1] = 0 ; vis[1] = 1 ; Q.push(1); while(!Q.empty()) { int now = Q.front(); Q.pop(); vis[now] = 0 ; for(int i = head[now] ; i!=-1 ;i = edge[i].next) //*遍历同起点的所有边 { int v = edge[i].to ; if(dis[v] > dis[now] + edge[i].val) { dis[v] = dis[now] + edge[i].val; if(!vis[v]) { Q.push(v); vis[v] = 1 ; } } } } } int main() { while(scanf("%d%d",&v,&u)!=EOF) { if(u==0&&v==0) break; ans = 0 ; for(int i = 0 ; i<=v;i++) { dis[i] = inf ; vis[i] = 0 ; } memset(head,-1,sizeof(head)); for(int i = 0 ; i < u ; i++) { int a , b , len ; scanf("%d%d%d",&a,&b,&len); add(a,b,len); } spfa(); cout<<dis[v]<<endl; } return 0 ; }
相关文章推荐
- html5 轻量级炫酷 js 粒子动画库
- apache flume collector 安装
- iOS初始化一个高德地图大概需要多少东西
- JS apply和call用处和用法
- oracle迁移数据文件
- TCP/IP详解学习笔记(3)-IP协议,ARP协议,RARP协议
- 安装Sublime Text 3 插件的方法
- Dynamics CRM2016 Update or Create parentcustomerid in Contact using web api
- 2016学习Linux的决心书(老男孩教育)
- [Baltic2014]sequence 解题报告
- Dynamics CRM2016 Update or Create parentcustomerid in Contact using web api
- Dynamics CRM2016 Update or Create parentcustomerid in Contact using web api
- Dynamics CRM2016 Update or Create parentcustomerid in Contact using web api
- SQL Server 2005使用OSQL连接出错
- 69 个经典 Spring 面试题和答案
- 《机器学习实战》AdaBoost算法的分析与实现
- 树——按“之”字形打印二叉树(层序遍历变型)
- 微信web开发者工具下载 微信web开发者工具使用方法
- php通过smtp邮件验证登陆的方法
- js定时器(执行一次、重复执行)