PAT L3-007. 天梯地图

最短路。求出一个最短路的$DAG$,然后在$DAG$上$dp$即可。

#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,sz,s,t,now;
struct X
{
    int u,v,f,L,T;
}e[5000000];
vector<int>G[600];
vector<int>FG[600];
vector<int>Top[600];
vector<int>ans1,ans2;

int A1,A2;

int timeS[600],timeT[600],dis[600],num[600],pre[600],f[600],In[600];
int disS[600],disT[600];

void spfaOneS()
{
    for(int i=0;i<n;i++) timeS[i]=0x7FFFFFFF, f[i]=0;
    timeS[s]=0; f[s]=1;  queue<int>Q; Q.push(s);

    while(!Q.empty())
    {
        int h = Q.front(); Q.pop(); f[h]=0;

        for(int i=0;i<G[h].size();i++)
        {
            int id = G[h][i];
            int to = e[id].v;

            if(timeS[h]+e[id].T<timeS[to])
            {
                timeS[to] = timeS[h]+e[id].T;
                if(f[to]==0)
                {
                    f[to]=1;
                    Q.push(to);
                }
            }
        }
    }
}

void spfaOneT()
{
    for(int i=0;i<n;i++) timeT[i]=0x7FFFFFFF, f[i]=0;
    timeT[t]=0; f[t]=1;  queue<int>Q; Q.push(t);

    while(!Q.empty())
    {
        int h = Q.front(); Q.pop(); f[h]=0;

        for(int i=0;i<FG[h].size();i++)
        {
            int id = FG[h][i];
            int to = e[id].u;

            if(timeT[h]+e[id].T<timeT[to])
            {
                timeT[to] = timeT[h]+e[id].T;
                if(f[to]==0)
                {
                    f[to]=1;
                    Q.push(to);
                }
            }
        }
    }
}

void WOne()
{
    for(int i=0;i<n;i++) dis[i]=0x7FFFFFFF, pre[i]=-1; dis[s]=0;
    queue<int>Q;
    for(int i=0;i<n;i++) if(In[i]==0) Q.push(i);
    while(!Q.empty())
    {
        int h=Q.front(); Q.pop();
        for(int i=0;i<Top[h].size();i++)
        {
            int id = Top[h][i];
            int to = e[id].v;
            if(dis[h]+e[id].L<dis[to])
            {
                dis[to] = dis[h]+e[id].L;
                pre[to] = h;
            }
            In[to]--; if(In[to]==0) Q.push(to);
        }
    }
}


void spfaTwoS()
{
    for(int i=0;i<n;i++) disS[i]=0x7FFFFFFF, f[i]=0;
    disS[s]=0; f[s]=1; queue<int>Q; Q.push(s);

    while(!Q.empty())
    {
        int h = Q.front(); Q.pop(); f[h]=0;

        for(int i=0;i<G[h].size();i++)
        {
            int id = G[h][i];
            int to = e[id].v;

            if(disS[h]+e[id].L<disS[to])
            {
                disS[to] = disS[h]+e[id].L;
                if(f[to]==0)
                {
                    f[to]=1;
                    Q.push(to);
                }
            }
        }
    }
}

void spfaTwoT()
{
    for(int i=0;i<n;i++) disT[i]=0x7FFFFFFF, f[i]=0;
    disT[t]=0; f[t]=1;  queue<int>Q; Q.push(t);

    while(!Q.empty())
    {
        int h = Q.front(); Q.pop(); f[h]=0;

        for(int i=0;i<FG[h].size();i++)
        {
            int id = FG[h][i];
            int to = e[id].u;

            if(disT[h]+e[id].L<disT[to])
            {
                disT[to] = disT[h]+e[id].L;
                if(f[to]==0)
                {
                    f[to]=1;
                    Q.push(to);
                }
            }
        }
    }
}

void WTwo()
{
    for(int i=0;i<n;i++) num[i]=0x7FFFFFFF, pre[i]=-1; num[s]=0;
    queue<int>Q;
    for(int i=0;i<n;i++) if(In[i]==0) Q.push(i);
    while(!Q.empty())
    {
        int h=Q.front(); Q.pop();
        for(int i=0;i<Top[h].size();i++)
        {
            int id = Top[h][i];
            int to = e[id].v;
            if(num[h]+1<num[to])
            {
                num[to] = num[h]+1;
                pre[to] = h;
            }
            In[to]--; if(In[to]==0) Q.push(to);
        }
    }
}

bool check()
{
    if(ans1.size()!=ans2.size()) return 0;
    for(int i=0;i<ans1.size();i++)
    {
        if(ans1[i]!=ans2[i]) return 0;
    }
    return 1;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d%d%d",&e[sz].u,&e[sz].v,&e[sz].f,&e[sz].L,&e[sz].T);
        G[e[sz].u].push_back(sz);
        FG[e[sz].v].push_back(sz);
        sz++;

        if(e[sz-1].f==0)
        {
            e[sz].u = e[sz-1].v;
            e[sz].v = e[sz-1].u;
            e[sz].f = e[sz-1].f;
            e[sz].L = e[sz-1].L;
            e[sz].T = e[sz-1].T;
            G[e[sz].u].push_back(sz);
            FG[e[sz].v].push_back(sz);
            sz++;
        }
    }
    scanf("%d%d",&s,&t);


    spfaOneS(); spfaOneT(); A1 = timeS[t];

    memset(In,0,sizeof In);
    for(int i=0;i<sz;i++)
    {
        if(timeS[e[i].u]+timeT[e[i].v]+e[i].T==timeS[t])
        {
            Top[e[i].u].push_back(i);
            In[e[i].v]++;
        }
    }

    WOne();

    now=t; stack<int>st;

    while(1)
    {
        st.push(now); now=pre[now];
        if(now==-1) break;
    }

    while(!st.empty()) { ans1.push_back(st.top()); st.pop(); }

    spfaTwoS(); spfaTwoT(); A2 = disS[t];
    for(int i=0;i<n;i++) Top[i].clear();
    memset(In,0,sizeof In);

    for(int i=0;i<sz;i++)
    {
        if(disS[e[i].u]+disT[e[i].v]+e[i].L==disS[t])
        {
            Top[e[i].u].push_back(i);
            In[e[i].v]++;
        }
    }

    WTwo(); now=t;

    while(1)
    {
        st.push(now); now=pre[now];
        if(now==-1) break;
    }

    while(!st.empty()) { ans2.push_back(st.top()); st.pop(); }

    if(check())
    {
        printf("Time = %d; Distance = %d:",A1,A2);
        for(int i=0;i<ans2.size();i++)
        {
            printf(" %d",ans2[i]);
            if(i<ans2.size()-1) printf(" =>");
            else printf("\n");
        }
    }

    else
    {
        printf("Time = %d:",A1);
        for(int i=0;i<ans1.size();i++)
        {
            printf(" %d",ans1[i]);
            if(i<ans1.size()-1) printf(" =>");
            else printf("\n");
        }

        printf("Distance = %d:",A2);
        for(int i=0;i<ans2.size();i++)
        {
            printf(" %d",ans2[i]);
            if(i<ans2.size()-1) printf(" =>");
            else printf("\n");
        }
    }

    return 0;
}

 

posted @ 2017-03-22 16:00  Fighting_Heart  阅读(208)  评论(0编辑  收藏  举报