zoukankan      html  css  js  c++  java
  • 最短路径统计

    noip2017 考了这个
    不过比这个不知道高到哪里去了
    但是毕竟可以用这个混到30分的呀.....

    做法

    大致有两种做法,可以spfa,也可以写dijkstra
    重要的地方都差不多,即用一个数组cnt[ i ] 表示 dis[ i ]有多少种走法

    实现

    dijkstra很好想,每次都是走的最短路直接更新即可
    spfa因为可能会反复进队,所以直接累加会导致重复计算。
    很美妙的做法是 每次出队就把 cnt[ k ] 赋成0

    题目可以做一下 luogu 1608

    代码

    dijkstra:

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 2010
    #define inf 1e9
    
    int mp[maxn][maxn],dis[maxn],n,m,c[maxn],cnt,p[maxn];
    int read(int x=0){scanf("%d",&x);return x;}
    bool vis[maxn];
    
    struct node{
        int a,b,w,nt;
    }e[maxn*maxn*2];
    
    inline void add(int x,int y,int z){
        e[++cnt].a=x,e[cnt].b=y,e[cnt].w=z;
        e[cnt].nt=p[x];p[x]=cnt;
    }
    
    inline void dijkstra(){
        priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
        for(int i=1;i<=n;i++)dis[i]=inf;
        dis[1]=0;c[1]=1;
        q.push(make_pair(dis[1],1));
        while(!q.empty()){
            pair<int,int> node=q.top();q.pop();
            int k=node.second;
            if(vis[k])continue;vis[k]=true;
            for(int i=p[k];i;i=e[i].nt){
                int kk=e[i].b;
                if(dis[kk]==dis[k]+e[i].w)
                    c[kk]+=c[k];
                else if(dis[kk]>dis[k]+e[i].w)
                    c[kk]=c[k],dis[kk]=dis[k]+e[i].w,q.push(make_pair(dis[kk],kk));
            }
        }
    }
    
    int main(){
        n=read(),m=read();
        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)mp[i][j]=-1;
        for(int i=1;i<=m;i++){
            int a=read(),b=read(),c=read();
            mp[a][b]=mp[a][b]==-1?c:min(c,mp[a][b]);
        }
        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)
            if(mp[i][j]!=-1)add(i,j,mp[i][j]);
        dijkstra();
        if(dis[n]==inf)puts("No answer");
        else printf("%d %d",dis[n],c[n]);
        return 0;
    }
    

    spfa:

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 2010
    #define inf 1e9
    
    int mp[maxn][maxn],dis[maxn],n,m,c[maxn];
    int read(int x=0){scanf("%d",&x);return x;}
    bool vis[maxn];
    
    inline void spfa(){
        queue<int>q;
        for(int i=1;i<=n;i++)dis[i]=inf;
        dis[1]=0;c[1]=1;q.push(1);
        while(!q.empty()){
            int k=q.front();q.pop();vis[k]=false;
            if(k==n)continue;
            for(int kk=1;kk<=n;kk++)if(mp[k][kk]!=-1){
                if(dis[kk]==dis[k]+mp[k][kk])c[kk]+=c[k];
                if(dis[kk]>dis[k]+mp[k][kk])
                    dis[kk]=dis[k]+mp[k][kk],c[kk]=c[k];
                if(c[kk]&&!vis[kk])vis[kk]=true,q.push(kk);
            }
            c[k]=0;
        }
    }
    
    int main(){
        n=read(),m=read();
        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)mp[i][j]=-1;
        for(int i=1;i<=m;i++){
            int a=read(),b=read(),z=read();
            mp[a][b]=mp[a][b]==-1?z:min(mp[a][b],z);
        }
        spfa();
        if(c[n]==0)puts("No answer");
        else printf("%d %d",dis[n],c[n]);
        return 0;
    }
    
  • 相关阅读:
    Flink的入门
    Hadoop/Spark相关面试问题总结
    什么事分布式系统
    分布式的本质
    spark的shuffle机制
    Yarn的资源隔离机制
    hadoop和spark相关参数的配置
    分布式常问问题
    转一篇分布式消息队列的文章
    jquery 重要知识点总结
  • 原文地址:https://www.cnblogs.com/DexterYsw/p/7894455.html
Copyright © 2011-2022 走看看