次短路poj3463

poj3463
大意:统计最小的长度个数+统计最小的长度+1的个数,大概就是求最短路和次短路的条数
更新的时候有5种情况,有个细节就是它得是二维的,一个表示节点编号,一个0/1表示它是次短路的还是最短路的,把结构体扔到队列里。需要更新的就是4种情况。
w<最小值
w=最小值
w<次小值
w=次小值

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<set>
#include<map>
#include<stack>
#include<cstring>
#define inf 2147483647
#define ls rt<<1
#define rs rt<<1|1
#define lson ls,nl,mid,l,r
#define rson rs,mid+1,nr,l,r
#define N 10010
#define For(i,a,b) for(long long i=a;i<=b;i++)
#define p(a) putchar(a)
#define g() getchar()

using namespace std;

long long T;
long long n,m,x,y,v,s,t,w,flag,num,now;
long long d[N][2];
long long f[N][2];
bool vis[N][2];
struct edge{
    long long n;
    long long v;
    edge *next;
}*e[N];

struct node{
    long long num;
    long long flag;
};

queue<node>q;

void in(long long &x){
    long long y=1;
    char c=g();x=0;
    while(c<'0'||c>'9'){
        if(c=='-')y=-1;
        c=g();
    }
    while(c<='9'&&c>='0'){
        x=(x<<1)+(x<<3)+c-'0';c=g();
    }
    x*=y;
}
void o(long long x){
    if(x<0){
        p('-');
        x=-x;
    }
    if(x>9)o(x/10);
    p(x%10+'0');
}

void push(long long x,long long y,long long v){
    edge *p;
    p=new edge();
    p->n=y;
    p->v=v;
    if(e[x]==0)
        e[x]=p;
    else{
        p->next=e[x]->next;
        e[x]->next=p;
    }
}

void spfa(){
    memset(d,0x3f,sizeof(d));
    d[s][0]=0;
    f[s][0]=1;
    q.push(node{s,0});
    while(!q.empty()){
        node tp=q.front();
        q.pop();
        now=tp.num;
        flag=tp.flag;
        vis[now][flag]=0;
        for(edge *i=e[now];i;i=i->next){
                w=d[now][flag]+i->v;

                if(w<d[i->n][0]){
                    if(d[i->n][0]!=d[0][0]){
                        d[i->n][1]=d[i->n][0];
                        f[i->n][1]=f[i->n][0];
                        if(!vis[i->n][1]){
                            q.push(node{i->n,1});
                            vis[i->n][1]=1;
                        }
                    }
                    f[i->n][0]=f[now][flag];
                    d[i->n][0]=w;
                    if(!vis[i->n][0]){
                        q.push(node{i->n,0});
                        vis[i->n][0]=1;
                    }
                }
                else
                    if(w==d[i->n][0])
                    f[i->n][0]+=f[now][flag];
                else
                    if(w<d[i->n][1]){
                        d[i->n][1]=w;
                        f[i->n][1]=f[now][flag];
                        if(!vis[i->n][1]){
                            q.push(node{i->n,1});
                            vis[i->n][1]=1;
                        }
                    }
                else
                    if(w==d[i->n][1])
                    f[i->n][1]+=f[now][flag];
        }
    }
}

void clear(){
    memset(f,0,sizeof(f));
    memset(vis,0,sizeof(vis));
    memset(e,0,sizeof(e));
}

int main(){
    in(T);
    while(T--){
        clear();
        in(n);in(m);
        For(i,1,m){
            in(x);in(y);in(v);
            push(x,y,v);
        }
        in(s);in(t);
        spfa();
        if(d[t][1]==d[t][0]+1)
            o(f[t][0]+f[t][1]);
        else
            o(f[t][0]);
        p('\n');
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/war1111/p/11223197.html