2011.07.15

POJ 3463

题意:求最短路和比最短路长1个单位的路的数量之和。

用dijkstra求出最短路和次短路数量,判断次短路是否比最短路长1单位输出和。

#include<cstdio>
#include<cstring>
#include<queue>
#define MAXE 10001
#define MAXV 1001
using namespace std;
const long long INF=(long long)1<<63-1;
typedef pair<long long,long long> pii;
long long t,m,n,V,E,pos=0,head[MAXV];
long long ans,d[2][MAXV],num[2][MAXV];
//bool can1[MAXV][MAXV],can2[MAXV][MAXE*2];
bool cannot=0;
struct Edge
{
    long long w,next,u,v;
}node[MAXE*2];
//无向图邻接表
struct dian
{
    long long id,d,c;
    bool operator <(const dian &a) const
    {
        return d>a.d;
    }
};
void add(long long u,long long v,long long w)
{
    if(u==v) return;
    node[pos].u=u;                 //如果指向自己的边则舍去
    node[pos].v=v;
    node[pos].w=w;
    node[pos].next=head[u];
    head[u]=pos++;
}
//S为起点标号
void dijkstra(long long s)
{
    for(long long i=0;i<=V;i++) d[0][i]=d[1][i]=INF;
    d[0][s]=0;
    num[0][s]=1;
    priority_queue<dian> q;
    bool done[2][MAXV];
    memset(done,0,sizeof(done));
    dian now;
    now.d=d[0][s];now.c=0;now.id=s;
    q.push(now);
    while(!q.empty()){
        dian u=q.top();q.pop();
        long long x=u.id,c=u.c;
            if(c==1 && x==4)
                int ting=100;
        if(done[c][x]) continue;
        done[c][x]=true;
        for(long long i=head[x];i!=-1;i=node[i].next){                   //亮点在松弛
            if(!done[0][node[i].v] && d[0][node[i].v]>u.d+node[i].w){    //发现更优解,把当前最短路赋给次短路,再更新最短路,均入队列
                d[1][node[i].v]=d[0][node[i].v];
                num[1][node[i].v]=num[0][node[i].v];
                num[0][node[i].v]=num[c][x];
                d[0][node[i].v]=u.d+node[i].w;
                dian temp;
                temp.c=0;temp.d=d[0][node[i].v];temp.id=node[i].v;
                q.push(temp);
                temp.c=1;temp.d=d[1][node[i].v];temp.id=node[i].v;
                q.push(temp);
            }
            else if(d[0][node[i].v]==u.d+node[i].w)                     //更新最短路数量
                num[0][node[i].v]+=num[c][x];
            else if(d[1][node[i].v]>u.d+node[i].w){                     //更新次短路
                d[1][node[i].v]=u.d+node[i].w;
                num[1][node[i].v]=num[c][x];
                dian temp;
                temp.c=1;temp.d=d[1][node[i].v];temp.id=node[i].v;
                q.push(temp);
            }
            else if(d[1][node[i].v]==u.d+node[i].w)                     //更新次短路数量
                num[1][node[i].v]+=num[c][x];
        }
    }
}
int  main()
{
    //freopen("in","r",stdin);
    //freopen("out","w",stdout);
    long long u,v,w,s,t,n;
    scanf("%lld",&n);
    for(long long l=0;l<n;l++){
        scanf("%lld%lld",&V,&E);
        pos=1;ans=0;
        memset(head,-1,sizeof(head));
        memset(num,0,sizeof(num));
        for(long long i=0;i<E;i++){
            scanf("%lld%lld%lld",&u,&v,&w);
            add(u,v,w);
        }
        scanf("%lld%lld",&s,&t);
        dijkstra(s);
        ans=num[0][t];
        if(d[1][t]==d[0][t]+1)
            ans+=num[1][t];
        printf("%lld\n",ans);
    }
    return 0;
}



不会求k短路然后一直以为直接求比最短路长1的路,各种错,唉~待会儿把次短路看一下吧= =

顺便吐槽一下西安的天气,在看了boat题解后豁然开朗…然后还是改了一个下午,小爷被热的各种脑残,ORZ……

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值