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;
}
原文地址:https://www.cnblogs.com/zufezzt/p/6600465.html