zoukankan      html  css  js  c++  java
  • luogu1608 路径统计 (spfa)

    题意:给一个有向图(无零边),要求找出最短路的数量(重边只计算一次)
    做spfa的时候,记一个cnt
    对于u-w->v如果dis[u]+w=dis[v],cnt[v]+=cnt[u]
    如果dis[u]+w<dis[v],cnt[v]=cnt[u]
    要注意的是,不论是大于还是等于,都需要把v加到队列里继续去更新
    (如果等于时不加,那么有可能v这个点在增加u->v之前更新过后面的点,这个后面的点就不会加从u来的路径)
    那既然等于时也要加入队列,那么有可能一个点就会给后面的更新两次,那么在更新过一次后直接把cnt[u]给成0即可
    然而不能让N这个点被给成0,其实N这个点根本就没必要被加入队列,发现有N的时候跳过即可
    最后答案就是cnt[N]

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int maxn=2020;
    
    int rd(){
        int x=0;char c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
        return x;
    }
    
    struct Edge{
        int a,b,l,ne;
    }eg[maxn*maxn];
    int N,M,egh[maxn],ect;
    int eg2[maxn][maxn];
    int ans[maxn];
    int dis[maxn];bool flag[maxn];
    queue<int> q;
    
    void adeg(int a,int b,int l){
        eg[ect].a=a;eg[ect].b=b;eg[ect].l=l;eg[ect].ne=egh[a];
        eg2[a][b]=l;egh[a]=ect++;
    }
    
    void spfa(){
        memset(dis,127,sizeof(dis));
        dis[1]=0;ans[1]=1;q.push(1);
        while(!q.empty()){
            int p=q.front();q.pop();flag[p]=0;
            if(p==N) continue;
            for(int i=egh[p];i!=-1;i=eg[i].ne){
                int j=eg[i].b;
                if(dis[j]==dis[p]+eg[i].l){
                    ans[j]+=ans[p];
                    if(!flag[j]) q.push(j);flag[j]=1;
                }
                if(dis[j]>dis[p]+eg[i].l){
                    dis[j]=dis[p]+eg[i].l;
                    ans[j]=ans[p];
                    if(!flag[j]) q.push(j);flag[j]=1;
                }
            }ans[p]=0;
        }
    }
    
    int main(){
        int i,j,k;
        N=rd();M=rd();
        memset(egh,-1,sizeof(egh));memset(eg2,127,sizeof(eg2));
        for(i=1;i<=M;i++){
            int a=rd(),b=rd(),c=rd();
            if(eg2[a][b]>c) adeg(a,b,c);
        }
        spfa();
        if(dis[N]>10*N) printf("No answer
    ");
        else printf("%d %d
    ",dis[N],ans[N]);
    }
  • 相关阅读:
    Asp.NET 4.0 ajax实例DataView 模板编程1
    ASP.NET 4.0 Ajax 实例DataView模板编程 DEMO 下载
    部分东北话、北京话
    .NET 培训课程解析(一)
    ASP.NET 4.0 Ajax 实例DataView模板编程2
    ASP.NET Web Game 架构设计1服务器基本结构
    ASP.NET Web Game 构架设计2数据库设计
    TFS2008 基本安装
    Linux上Oracle 11g安装步骤图解
    plsql developer远程连接oracle数据库
  • 原文地址:https://www.cnblogs.com/Ressed/p/9354320.html
Copyright © 2011-2022 走看看