POJ1511 SPFA

第一次做SPFA,本来觉得会很难很难写,所以一直都没有去涉及这个方面的题目。在FUZHOU网络赛上遇到了属于SPFA算法的题目,可是我却完全不知道。这次网络预选赛又是3题,还是没能去成现场赛... 最后一年了,我还是这么弱小,A题还是那么慢,所以要好好把握写题的速度尽量快起来!!

SPFA--Bellman-Ford的升级版,却是很好写的。另外几方面还是很省空间的。因为用边来存贮嘛,比如邻接矩阵,在稀疏图的条件下很快很暴力的就可以写出来。

算法我理解的很快,也只写了个裸的SPFA,没有去优化它,多做几个题练练手吧!

代码如下(不懂的可以问我哈):

#include<stdio.h>
#include<queue>
#include<string.h>
#define INF 1234567891011
#define MAXN 1000005
using namespace std;

struct Edge
{
	long v;
	long price;
	Edge *next;
}edge[2][MAXN],*ptr[2][MAXN];//存储两个图 另外实现邻接链表!
long dist[MAXN];

int V,E;
int edgeNum;

void addEdge(long a,long b,long c)
{
            Edge *p,*q;
            p=&edge[0][edgeNum];
            q=&edge[1][edgeNum];
            edgeNum++;

            p->v=b;
            p->price=c;
            p->next=ptr[0][a];
            ptr[0][a]=p;

            q->v=a;
            q->price=c;
            q->next=ptr[1][b];
            ptr[1][b]=q;
}

void getEdges()
{
            int i,j;
            edgeNum=0;
            long a,b,c;
            for( i=1;i<=E;i++ )
            {
                    scanf( "%lld %lld %lld",&a,&b,&c );
                    addEdge(a,b,c);
            }
}

bool used[MAXN];

void SPFA( int graph,int start )
{
            memset( used,0,sizeof(used) );
            memset( dist,0x7F,sizeof(dist) );
            dist[start]=0;
            queue<int>queue;
            while( !queue.empty() )queue.pop();
            queue.push(start);
            used[start]=true;
            while( !queue.empty() )
            {
                        long u=queue.front();
                        queue.pop();
                        Edge *p=ptr[graph][u];
                        while( p!=NULL )
                        {
                                    long w=p->price;
                                    long v=p->v;
                                    p=p->next;
                                    if( dist[v]>dist[u]+w )
                                    {
                                                dist[v]=dist[u]+w;
                                                if( !used[v] ){
                                                            queue.push(v);
                                                            used[v]=true;
                                                }
                                    }
                        }
                        used[u]=false;
            }
}

int main()
{
            int T;
            scanf( "%d",&T );
            while( T-- )
            {
                        scanf( "%d %d",&V,&E );
                        int i,j,k;
                        getEdges();
                        long ans=0;
                        for( k=0;k<2;k++ )
                        {
                                    SPFA( k,1 );
                                    for( i=2;i<=V;i++ )
                                                ans+=dist[i];
                        }
                        printf( "%lld\n",ans );
            }
            return 0;
}

这题用的正宗的链表哦~~ 87!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值