2011.07.11

XDOJ 1082

题意为求S(a,b)+min(S(s,a),S(s,b))

#include <iostream>
#include <stdio.h>
#include <cmath>
#include <cstring>
#include <memory.h>
#include <algorithm>
#include <fstream>
#include <cstring>
#define INF 2140000000
#define MAXE 200001
#define MAXV 100001
struct node
{
   int v,w,next;
}e[MAXE*2];

int head[MAXV],d[MAXV],q[MAXV],pre[MAXV];  //d存放最短距离,pre存放最短路径
int pos=0,V,E;
void spfa(int x)
{
   bool done[MAXV];
   memset(done,0,sizeof(done));
   int i,f,r,ns,now;
   for(i=0;i<=V;i++) d[i]=INF;
   d[x]=0; q[1]=x; done[x]=1;
   f=1; r=2;
   while(f!=r)
   {
       now=q[f++];        // 队首元素
       if(f>V) f=1;
       done[now]=0;
       for(i=head[now];i!=-1;i=e[i].next)
       {
           ns=e[i].v;
           if(d[now]+e[i].w<d[ns])
           {
               d[ns]=d[now]+e[i].w;
               pre[ns]=now;
               if(done[ns]==0)
               {
                   done[ns]=1;
                   if(f<=V&&d[ns]<d[q[f+1]])    //  优化
                   {
                       q[--f]=ns;
                   }
                   else
                   {
                       q[r]=ns;
                       r++;
                       if(r>V) r=1;
                   }
               }
           }
       }
   }
}
int main()
{
   freopen("in","r",stdin);
   int i,u,v,cc,s,dd,ddd;
   scanf("%d%d%d%d%d",&E,&V,&s,&dd,&ddd);
   memset(head,-1,sizeof(head));
   for(i=1;i<=E;i++)
   {
       scanf("%d%d%d",&u,&v,&cc);
       e[++pos].v=v; e[pos].w=cc; e[pos].next=head[u];
       head[u]=pos;
       e[++pos].v=u; e[pos].w=cc; e[pos].next=head[v];
       head[v]=pos;
   }
   spfa(s);
   int s1;
   if(d[dd]>d[ddd]) s1=d[ddd];
   else s1=d[dd];
   spfa(dd);
   printf("%d\n",d[ddd]+s1);
   return 0;
}

SPFA+循环队列+SLF模板:

#include <cstdio>
#include <cstring>
#define INF ((long long)1<<63-1)
#define MAXE 200001
#define MAXV 100001
struct node
{int v,w,next;} e[MAXE*2];
int head[MAXV],d[MAXV],q[MAXV],pre[MAXV];//d存放最短距离,pre存放最短路径
int pos=0,V,E;
void add(int u,int v,int w)
{
    if(u==v) return ;                   //指向自己的边舍弃
    e[pos].v=v;e[pos].w=w;
    e[pos].next=head[u];
    head[u]=pos++;
}
void spfa(int x)                      //x为起点
{
   bool done[MAXV];
   memset(done,0,sizeof(done));
   int i,f,r,ns,now;
   for(i=0;i<=V;i++) d[i]=INF;
   d[x]=0; q[1]=x; done[x]=1;
   f=1; r=2;
   while(f!=r){
       now=q[f++];        // 队首元素
       if(f>V) f=1;
       done[now]=0;
       for(i=head[now];i!=-1;i=e[i].next){
           ns=e[i].v;
           if(d[now]+e[i].w<d[ns]){
               d[ns]=d[now]+e[i].w;
               pre[ns]=now;
               if(done[ns]==0){
                   done[ns]=1;
                   if(f<=V&&d[ns]<d[q[f+1]])   //SLF:Small Label First,队首元素为f,在d[ns]最小时ns加到队首而不是队尾,否则加到队尾
                       q[--f]=ns;
                   else   {q[r++]=ns;if(r>V) r=1;}
               }
           }
       }
   }
}
int main()
{
   freopen("in","r",stdin);
   int i,u,v,w,s,t;
   scanf("%d%d%d%d",&E,&V,&s,&t);
   memset(head,-1,sizeof(head));
   for(i=1;i<=E;i++){
       scanf("%d%d%d",&u,&v,&w);
       add(u,v,w);
       add(v,u,w);
   }
   spfa(s);
   printf("%d\n",d[t]);
   return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值