zoukankan      html  css  js  c++  java
  • 次短路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('
    ');
        }
        return 0;
    }
  • 相关阅读:
    Android 关于ExpandableListView控件setOnChildClickListener无效问题
    Android SnapHelper
    Android java判断字符串包含某个字符段(或替换)
    Android中的CharSequence和String
    Java时间和时间戳的相互转换
    比较运算符和函数(四十一)
    数值运算符和函数(四十)
    字符函数(三十九)
    多表删除(三十八)
    无限级分类表设计(三十七)
  • 原文地址:https://www.cnblogs.com/war1111/p/11223197.html
Copyright © 2011-2022 走看看