POJ-1511 初探Bellman-Ford,再水SPFA模板题..
来源:互联网 发布:win10没有windows聚焦 编辑:程序博客网 时间:2024/06/05 17:26
昨天狐狸大大交流~~会了bellman-ford..
bellman-ford简单概括就是:
/*
d [ i ] 来记录源点到 i 点的最小距离,初始值源点的 d [ ] 为0,其他的点为一个足够大的数
line[ ] .start 表示线段的起点, line[ ] .end 表示线段的终点, line[ ] .w 表示线段的权值,
*/
for ( times=1 to NumOfPoint )
for ( i = 1 to NumOfLine )
relax ( line[ i ] )
其核心就在 ralex ,
relax
{
d [ line[i].end ] = min ( d [ line[i].end ] , d [ line[i].start ] + line[ i ] .w )
}
思想有点类似kruscal..但其每次都是扫描所有的边...写的话..5行之内搞定...但是有tick就是如果题目没有强调...要判断有没有负环...有负环的话那么是无解的..因为可以无限爱负环上转圈而使得值无限的小...
SPFA是在bellman-ford上的改进...因为bellman-ford每次都要扫描所有的边..这是很浪费的..因为大部分的边并没有更新..SPFA则用一个队列 ( 其实也没必要是队列..甚至是个无序的集合都行,目的是标记当前更新过但还未拓展的点 ) 优化...
思想就是如果更新了一个点..那么如果有新更新..那肯定和这个更新的点有关...这样就能大大的减少不必要的扫描...每次更新了一个点后.. 将这个点入队...后面当队首到达这个点时,这个点出队..并扫面这个点为起点的所有边来更新...注意的是队列里同一个点只能出现一次...但一个点是可能多次入队的...因为通过这个点更新了相邻的..反过来这些相邻的点在后面的更新中可能又能来更新这个点.. (这个过程用一个bool数组来维护...入队时标记为true..出队之前对其有更新就入不了队...当出队时..则讲其又还原为false..那么后面如果又更新到了...还能入队..)
介于每次都是更新时扫面的是某点为起点的所有线段...那自然想到用前向星的方式来存储边最方便...即省了空间又高度符合所要做的操作...
POJ1151 题目的意思抽象出来就是给一个有向图..求 1到所有点的最小距离之和与所有点到1最小距离之和相加的最小值....用一个正向的原图做一次SPFS..再将所有边反过来做一次SPFS..轻轻松松鸭梨不大.....
Program:
#include<iostream>#include<queue>#define oo 2000000000000000llusing namespace std;struct pp{ int x,y,k; }line[1000001];struct pq{ int start,end; }link[1000001];int t,p,q,i,j;long long ans,d[1000001];bool used[1000001];queue<int> myqueue;bool cmp(pp a,pp b){ return a.x<b.x; } void built(){ int i,j,k,h; for (i=1;i<=p;i++) { link[i].start=0; link[i].end=-1; } i=1; while (i<=q) { k=line[i].x; link[k].start=i; i++; while (i<=q && line[i].x==k) i++; link[k].end=i-1; }}long long SPFA(){ int i,j,h,k; long long ans=0; memset(used,false,sizeof(used)); for (i=2;i<=p;i++) d[i]=oo; d[1]=0; used[1]=true; while (!myqueue.empty()) myqueue.pop(); myqueue.push(1); while (!myqueue.empty()) { h=myqueue.front(); myqueue.pop(); used[h]=false; for (i=link[h].start;i<=link[h].end;i++) { k=line[i].y; if (d[k]>d[h]+line[i].k) { d[k]=d[h]+line[i].k; if (!used[k]) { myqueue.push(k); used[k]=true; } } } } for (i=2;i<=p;i++) ans+=d[i]; return ans;}int main(){ scanf("%d",&t); while (t--) { scanf("%d%d",&p,&q); for (i=1;i<=q;i++) scanf("%d%d%d",&line[i].x,&line[i].y,&line[i].k); sort(line+1,line+1+q,cmp); built(); ans=SPFA(); for (i=1;i<=q;i++) { j=line[i].x; line[i].x=line[i].y; line[i].y=j; } sort(line+1,line+1+q,cmp); built(); ans+=SPFA(); printf("%I64d\n",ans); } return 0; }
- POJ-1511 初探Bellman-Ford,再水SPFA模板题..
- POJ 3259-Wormholes (Bellman-Ford&&SPFA) (模板题)
- poj 3259 Bellman-ford + SPFA
- poj 3259 spfa + Bellman-Ford
- poj 3259 Wormholes(SPFA || Bellman-Ford)
- poj 3259 Wormholes【Bellman-Ford Vs SPFA】
- poj 3259 Wormholes SPFA // Bellman-ford
- POJ 3259 Wormholes (Bellman-ford或SPFA)
- Bellman-Ford||SPFA-POJ-3259-Wormholes
- Bellman-Ford||SPFA-POJ-2240-Arbitrage
- POJ 3259 Wormholes (SPFA&&BellMan Ford)
- 【POJ】3259 Wormholes bellman-ford | SPFA
- Wormholes( POJ 3259)(Bellman-Ford+SPFA)(判断是否有负权环)(最短路模板)
- Bellman-Ford算法模板题——POJ 3259
- Bellman-Ford&SPFA算法
- Bellman-Ford || SPFA :Wormholes
- Bellman-ford Spfa hihocoder1903
- bellman-ford and SPFA
- ClientScript.RegisterStartupScript 不起作用
- apache顶级域名跳转
- list--初步学习STL
- System.Drawing.Image图像 批量生成并显示在web页面上
- 查看对象所属文件组
- POJ-1511 初探Bellman-Ford,再水SPFA模板题..
- ubuntu下在终端中普通用户与root之间的切换
- hg 自动 push
- Inside Market Data Award Winners 2010 - Vendor Categories
- android ROM
- TeraGen例子疑惑
- 原型法(prototyping)的改进
- jbuilder生成JAR和EXE文件
- 快译分组后汇总