zoukankan      html  css  js  c++  java
  • PAT (Advanced Level) 1003. Emergency (25)

    最短路+dfs

    先找出可能在最短路上的边,这些边会构成一个DAG,然后在这个DAG上dfs一次就可以得到两个答案了。

    也可以对DAG进行拓扑排序,然后DP求解。

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<cstdio>
    #include<queue>
    #include<vector>
    using namespace std;
    
    const int INF=0x7FFFFFFF;
    const int maxn=550;
    int n,m,C1,C2,tot,ans1,ans2;
    int val[maxn];
    struct Edge
    {
        int u,v,L;
    }e[600000];
    int f[600000];
    vector<int>g[maxn];
    int dis[2][maxn];
    int h[maxn];
    
    void init()
    {
        tot=0;
        for(int i=0;i<=500;i++) g[i].clear();
        memset(h,0,sizeof h);
    }
    
    void add(int a,int b,int c)
    {
        e[tot].u=a,e[tot].v=b,e[tot].L=c;
        g[a].push_back(tot);
        tot++;
    }
    
    void read()
    {
        scanf("%d%d%d%d",&n,&m,&C1,&C2);
        for(int i=0;i<n;i++) scanf("%d",&val[i]);
        for(int i=1;i<=m;i++)
        {
            int u,v,L; scanf("%d%d%d",&u,&v,&L);
            add(u,v,L);
            add(v,u,L);
        }
    }
    
    void SPFA(int f,int st)
    {
        for(int i=0;i<=500;i++) dis[f][i]=INF;
        dis[f][st]=0;
        int flag[maxn]; memset(flag,0,sizeof flag);
        queue<int>Q; Q.push(st); flag[st]=1;
        while(!Q.empty())
        {
            int head= Q.front(); Q.pop(); flag[head]=0;
            for(int i=0;i<g[head].size();i++)
            {
                int id=g[head][i];
                if(dis[f][head]+e[id].L<dis[f][e[id].v])
                {
                    dis[f][e[id].v]=dis[f][head]+e[id].L;
                    if(flag[e[id].v]==0)
                    {
                        Q.push(e[id].v);
                        flag[e[id].v]=1;
                    }
                }
            }
        }
    }
    
    void dfs(int x,int v)
    {
        if(x==C2)
        {
            ans1++; ans2=max(ans2,v);
            return ;
        }
    
        for(int i=0;i<g[x].size();i++)
        {
            int id=g[x][i];
            if(f[id]==0) continue;
            dfs(e[id].v,v+val[e[id].v]);
        }
    }
    
    void work()
    {
        int len=dis[0][C2];
    
        for(int i=0;i<tot;i++)
            if(dis[0][e[i].u]+e[i].L+dis[1][e[i].v]==len)
                f[i]=1;
    
        ans1=0; dfs(C1,val[C1]);
        printf("%d %d
    ",ans1,ans2);
    }
    
    int main()
    {
        init();
        read();
        SPFA(0,C1);
        SPFA(1,C2);
        work();
        return 0;
    }
  • 相关阅读:
    匿名对象
    再次安装xampp遇到的各类问题汇总
    jupyter notebook添加Anaconda虚拟环境的python kernel
    1003. 我要通过!
    大数据分析-excel常用技巧
    Jupyter Notebook 修改默认打开的文件夹的位置
    A*算法介绍
    MATLAB常用函数(不定时更新)
    2019数学建模美赛感悟
    Windows许可证即将到期激活教程
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5495932.html
Copyright © 2011-2022 走看看