【SPFA】-DLUT1218-裸题
来源:互联网 发布:app推广链接php源码 编辑:程序博客网 时间:2024/06/14 06:22
题目链接:
题目描述:最短路最裸题
解题思路:
比赛时候用DIJ+heap过了,注意long long 是个坑。
例会讲了SPFA算法,拿这题试验一下。
所谓SPFA就是对边进行BFS。。不太严密,应该说是通过类似于BFS的方式对dis[i]这个表示i点距起点最短距离的数组进行更新。
嗯。。用inqueue数组来判断某点是否已经在队列里,把取出的队列首点能达到的边进行以下判断:
if(dis[from]+cost<dis[to])
如果成立,更新(松弛)dis[to]的值。
并判断to是否正在队列内,不在的话就放进队列里。
AC代码:
#include <iostream>#include <cstdio>#include <queue>#include <stack>#include <algorithm>#include <cstring>#include <cstdlib>#include <cmath>#include <vector>using namespace std;typedef long long ll;const int INF=0x3f3f3f3f;const int maxn=10050;struct edge{int end,cost;edge(int e,int c){end=e;cost=c;}};vector<edge> eg[maxn];int n,m;ll dis[maxn];bool inqueue[maxn];queue<int> q;ll SPFA(int S,int E){memset(dis,INF,sizeof(dis));memset(inqueue,0,sizeof(inqueue));while(!q.empty())q.pop();q.push(S);dis[S]=0;inqueue[S]=1;while(!q.empty()){int from;from=q.front();q.pop();inqueue[from]=0;for(int i=0;i<eg[from].size();i++){int to=eg[from][i].end;if(dis[from]+eg[from][i].cost<dis[to]){dis[to]=dis[from]+eg[from][i].cost;if(!inqueue[to]){q.push(to);inqueue[to]=1;}}}}return dis[E];}void add_edge(int from,int to,int w){int i,flag=0;for(i=0;i<eg[from].size();i++){if(eg[from][i].end==to){eg[from][i].cost=min(eg[from][i].cost,w);flag=1;break;}}if(!flag)eg[from].push_back(edge(to,w));}int main(){freopen("input.txt","r",stdin);int T,i,j,from,to,w,A,B,C;cin>>T;while(T--){for(i=0;i<maxn;i++)eg[i].clear();cin>>n>>m;while(m--){cin>>from>>to>>w;add_edge(from,to,w);}cin>>A>>B>>C;ll ans=0;ans+=SPFA(A,B);ans+=SPFA(B,C);cout<<ans<<endl;} return 0;}
对SPFA的理解:
= =
本来想写。但脑子突然乱了。。怎么回事来的。。我还是先睡吧,明天的
DIJ+HEAP 方法
#include <iostream> #include <cstdio> #include <queue> #include <vector> #include <cstring> using namespace std; const int maxn=10050;const int INF = 0x3f3f3f3f; typedef long long ll;typedef pair <ll,int> pii; struct edge { int end; int value; edge(int a,int b){end=a;value=b;} }; int vis[maxn]; ll dis[maxn];int n,m,A,B,C; vector<edge> eg[maxn]; priority_queue <pii,vector<pii>,greater<pii> > q; void dijkstra(int st) { memset(dis,INF,sizeof(dis)); memset(vis,0,sizeof(vis)); while(!q.empty())q.pop(); int from=st,to,i; dis[from]=0; q.push(make_pair(dis[from],from)); while(!q.empty()) { pii t=q.top();q.pop(); from=t.second; if(vis[from])continue; vis[from]=1; for(i=0;i<eg[from].size();i++) { to=eg[from][i].end; if(!vis[to]&&dis[from]+eg[from][i].value<dis[to]) { dis[to]=dis[from]+eg[from][i].value; q.push(make_pair(dis[to],to)); } } } } void input() { int flag=0,i,j,from,to,w; while(m--) { cin>>from>>to>>w; for(i=0;i<eg[from].size();i++) { flag=0; if(eg[from][i].end==to) { eg[from][i].value=min(eg[from][i].value,w); flag=1;break; } } if(!flag) { eg[from].push_back(edge(to,w)); } } cin>>A>>B>>C; /*for(i=1;i<=n;i++) { for(j=0;j<eg[i].size();j++) cout<<i<<"-->"<<eg[i][j].end<<"need"<<eg[i][j].value<<endl; } cout<<endl; */} int main() { //freopen("input.txt","r",stdin); int i,j,T; cin>>T; while(T--) { ll ans=0; cin>>n>>m; for(i=0;i<maxn;i++)eg[i].clear(); input(); dijkstra(A); ans+=dis[B]; dijkstra(B); ans+=dis[C]; cout<<ans<<endl; } return 0; }
0 0
- 【SPFA】-DLUT1218-裸题
- dlut1218-spfa(链式向前星)模板题
- SPFA
- spfa
- spfa
- SPFA
- SPFA
- SPFA
- SPFA
- spfa
- SPFA
- SPFA
- SPFA
- SPFA
- SPFA
- spfa
- spfa
- spfa
- ACM比大小
- 一个五位数,ABCDE*4=EDCBA,求出这样的五位数。
- WinRAR 4.00 简体中文正式版+注册机
- 排序算法小结
- C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区
- 【SPFA】-DLUT1218-裸题
- svn server 配置 与TortoiseSVN、Ankhsvn+VS使用 及 问题
- 2014-04-04
- computeValuesWithHarfbuzz -- need to force to single run
- 我的公眾微信
- 关于thread中断问题
- Ubuntu Touch Emulator: Installation And Usage In Ubuntu 14.04, 13.10 And 12.04
- 程序员该思考的
- 通用工具auto_ptr 模板智能指针