• PAT L3-011. 直捣黄龙


    最短路。

    先求出一个只包含最短路的$DAG$,然后在$DAG$上$dp$一下就可以了。英文变数字还有$map$转一下。

    #include<map>
    #include<set>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<string>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    using namespace std;
    
    int n,m,s,t,num[250];
    char tmp[100],A[100],B[100];
    
    map<string,int>xx;
    map<int,string>yy;
    
    vector<int>G[250],nG[250];
    int Time[250][250];
    
    int disS[250],disT[250],f[250];
    
    int U[250*250],V[250*250],In[250];
    
    int ss[250],pre[250],sl[250],dp[250];
    
    void spfaS()
    {
        memset(f,0,sizeof f);
        for(int i=1;i<=n;i++) disS[i]=0x7FFFFFFF;
        queue<int>Q; Q.push(s); f[s]=1; disS[s]=0;
    
        while(!Q.empty())
        {
            int h = Q.front(); Q.pop(); f[h]=0;
            for(int i=0;i<G[h].size();i++)
            {
                int to = G[h][i];
                if(disS[h]+Time[h][to]<disS[to])
                {
                    disS[to] = disS[h]+Time[h][to];
                    if(f[to]==0)
                    {
                        f[to]=1;
                        Q.push(to);
                    }
                }
            }
        }
    }
    
    void spfaT()
    {
        memset(f,0,sizeof f);
        for(int i=1;i<=n;i++) disT[i]=0x7FFFFFFF;
        queue<int>Q; Q.push(t); f[t]=1; disT[t]=0;
    
    
        while(!Q.empty())
        {
            int h = Q.front(); Q.pop(); f[h]=0;
            for(int i=0;i<G[h].size();i++)
            {
                int to = G[h][i];
                if(disT[h]+Time[h][to]<disT[to])
                {
                    disT[to] = disT[h]+Time[h][to];
                    if(f[to]==0)
                    {
                        f[to]=1;
                        Q.push(to);
                    }
                }
            }
        }
    }
    
    void W()
    {
        queue<int>Q; Q.push(s); dp[s]=1;
    
        while(!Q.empty())
        {
            int h = Q.front(); Q.pop();
            for(int i=0;i<nG[h].size();i++)
            {
                int to = nG[h][i];
                dp[to]+=dp[h];
                if(sl[h]+1>sl[to])
                {
                    sl[to] = sl[h]+1;
                    ss[to] = ss[h]+num[to];
                    pre[to]=h;
                }
    
                else if(sl[h]+1==sl[to])
                {
                    if(ss[h]+num[to]>ss[to])
                    {
                        sl[to] = sl[h]+1;
                        ss[to] = ss[h]+num[to];
                        pre[to]=h;
                    }
                }
                In[to]--;
                if(In[to]==0) Q.push(to);
            }
        }
    }
    
    int main()
    {
        scanf("%d%d",&n,&m); scanf("%s%s",A,B);
    
        xx[A]=1; yy[1]=A;
        for(int i=2;i<=n;i++)
        {
            scanf("%s",tmp); xx[tmp]=i; yy[i]=tmp;
            scanf("%d",&num[i]);
        }
        s=1; t=xx[B];
    
        for(int i=1;i<=m;i++)
        {
            int P;
            scanf("%s%s",A,B); scanf("%d",&P);
            int u = xx[A], v = xx[B];
    
            U[i] = u; V[i]=v;
            Time[u][v]=Time[v][u]=P;
            G[u].push_back(v);
            G[v].push_back(u);
        }
    
        spfaS(); spfaT();
    
        for(int i=1;i<=m;i++)
        {
            if(disS[U[i]]+disT[V[i]]+Time[U[i]][V[i]]==disS[t])
            {
                nG[U[i]].push_back(V[i]);
                In[V[i]]++;
            }
            if(disS[V[i]]+disT[U[i]]+Time[U[i]][V[i]]==disS[t])
            {
                nG[V[i]].push_back(U[i]);
                In[U[i]]++;
            }
        }
    
        W();
    
        vector<int>Ans;
        stack<int>St;
    
        int now=t;
        while(1)
        {
            if(now==0) break;
            St.push(now);
            now=pre[now];
        }
    
        while(!St.empty())
        {
            Ans.push_back(St.top());
            St.pop();
        }
    
        for(int i=0;i<Ans.size();i++)
        {
            cout<<yy[Ans[i]];
            if(i<Ans.size()-1) printf("->");
            else printf("
    ");
        }
    
        printf("%d %d %d
    ",dp[t],disS[t],ss[t]);
    
        return 0;
    }
  • 相关阅读:
    linux下给U盘分区&制作文件系统
    迭代器 配接器
    仿函数
    在查询用户的权限的时候 使用左外连接 和 access数据库中左外连接
    C# 想要程序文件移动 而数据保持相对位置
    C# 第三方控件 下面的Item不显示了
    C# 第三方控件 错误 LC-1
    c# 第三方控件 闪退
    access 语句错误
    poj 1469(二分图 最大匹配)
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6600465.html
Copyright © 2020-2023  润新知