zoukankan      html  css  js  c++  java
  • 1003 Emergency (25 分)(求最短路径)

    给出N个城市,m条无向边。每个城市中都有一定数目的救援小组,所有边的边权已知。现在给出起点和终点,求从起点到终点的最短路径条数及最短经上的救缓小组数目只和。如果有多条最短路径,则输出数目只和最大的

    Dijkstra 做法

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,s,u;
    const int N=1000;
    const int inf=0x3f3f3f3f;
    int mp[N][N];
    int dis[N];
    bool vis[N];
    int value[N];
    int num[N];
    int w[N];
    void Dijkstra()
    {
        fill(vis,vis+N,false);
        fill(dis,dis+N,inf);
        fill(w,w+N,0);
        fill(num,num+N,0);
        num[s]=1;//赋值
        w[s]=value[s];//赋值
        for(int i=0;i<n;i++) dis[i]=mp[s][i];
        dis[s]=0;
        for(int i=0;i<n-1;i++){
            int u=-1;
            int minn=inf;
            for(int j=0;j<n;j++){
                if(!vis[j]&&dis[j]<minn){
                    u=j;
                    minn=dis[j];
                }
            }
            if(u==-1) return;
            vis[u]=true;
            for(int j=0;j<n;j++){
                if(!vis[j]&&dis[u]+mp[u][j]<=dis[j]){
                    if(mp[u][j]+dis[u]<dis[j]){
                        dis[j]=mp[u][j]+dis[u];
                        num[j]=num[u];
                        w[j]=w[u]+value[j];
                    }
                    else{
                        num[j]+=num[u];
                        if(w[u]+value[j]>w[j]){
                            w[j]=w[u]+value[j];
                        }
                    }
                }
            }
    
        }
    }
    int main()
    {
        scanf("%d %d %d %d",&n,&m,&s,&u);
        for(int i=0;i<n;i++) scanf("%d",&value[i]);
        memset(mp,inf,sizeof(mp));
        while(m--){
            int a,b,c;
            scanf("%d %d %d",&a,&b,&c);
            mp[a][b]=mp[b][a]=c;
        }
        Dijkstra();
        printf("%d %d",num[u],w[u]);
    
        return 0;
    }

    spfa做法

    #include<bits/stdc++.h>
    
    using namespace std;
    int n,m,s,v;
    struct node
    {
        int to;
        int dis;
        node(int _to=0,int _dis=0):to(_to),dis(_dis){}
    };
    const int N=1010;
    int dis[N];
    bool vis[N];
    int w[N];
    int num[N];
    int value[N];
    vector<node>mp[N];
    set<int>st[N];
    const int inf=0x3f3f3f3f;
    void spfa()
    {
        fill(dis,dis+N,inf);
        fill(vis,vis+N,false);
        fill(w,w+N,0);
        w[s]=value[s];
        num[s]=1;
        queue<int>Q;
        Q.push(s);
        vis[s]=true;
        dis[s]=0;
        while(!Q.empty()){
            int u=Q.front();
            Q.pop();
            vis[u]=false;
            for(int i=0;i<mp[u].size();i++){
                int to=mp[u][i].to;
                int diss=mp[u][i].dis;
                if(diss+dis[u]<dis[to]){
                    dis[to]=diss+dis[u];
                    w[to]=w[u]+value[to];
                    num[to]=num[u];
                    st[to].clear();
                    st[to].insert(u);
                    if(!vis[to]){
                        Q.push(to);
                        vis[to]=true;
                    }
                }
                else if(diss+dis[u]==dis[to]){
                    if(w[to]<w[u]+value[to]){
                        w[to]=w[u]+value[to];               
                    }
                    st[to].insert(u);
                    num[to]=0;//因为spfa会重复到一个点 所以可能重复的边
                    for(set<int>::iterator it=st[to].begin();it!=st[to].end();++it){
                        num[to]+=num[*it];
                    }
                    if(!vis[to]){
                        Q.push(to);
                        vis[to]=true;
                    }
                }
            }
        }
    }
    int main()
    {
        scanf("%d %d %d %d",&n,&m,&s,&v);
        for(int i=0;i<n;i++) scanf("%d",&value[i]);
        for(int i=0;i<n;i++) mp[i].clear();
        while(m--){
            int a,b,c;
            scanf("%d %d %d",&a,&b,&c);
            mp[a].push_back(node(b,c));
            mp[b].push_back(node(a,c));
        }
        spfa();
        printf("%d %d
    ",num[v],w[v]);
    
        return 0;
    }
  • 相关阅读:
    SQL实战(四)
    SQL实战(三)
    SQL实战(二)
    数据库SQL实战(一)
    算法(二)——背包问题
    华为机试(五)
    算法(一)
    华为机试练习(四)
    华为往年机试题目(三)
    T分布(T-Distribution)
  • 原文地址:https://www.cnblogs.com/chenchen-12/p/10084659.html
Copyright © 2011-2022 走看看