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;
    }
  • 相关阅读:
    把git项目放到个人服务器上
    关于fcitx无法切换输入法的问题解决
    博客变迁通知
    (欧拉回路 并查集 别犯傻逼的错了) 7:欧拉回路 OpenJudge 数据结构与算法MOOC / 第七章 图 练习题(Excercise for chapter7 graphs)
    (并查集) HDU 1856 More is better
    (并查集 不太会) HDU 1272 小希的迷宫
    (并查集 注意别再犯傻逼的错了) HDU 1213 How Many Tables
    (最小生成树 Kruskal算法) 51nod 1212 无向图最小生成树
    (并查集) HDU 1232 畅通工程
    (最小生成树 Prim) HDU 1233 还是畅通工程
  • 原文地址:https://www.cnblogs.com/chenchen-12/p/10084659.html
Copyright © 2011-2022 走看看