PAT (Advanced Level) 1111. Online Map (30)

预处理出最短路再进行暴力dfs求答案会比较好。直接dfs效率太低。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;

int n,m;
int st,en;
struct Edge
{
    int u,v,len,time;
}e[2000000+10];
int tot=0;
vector<int>g[600];
int Dis[600],Tim[600];
bool flag[600];

int ans_len,ans_time,ans_sz,ans_count;
int path[600],ans_path[600];

vector<int>p1,p2;
int Distance,Time;

void addedge(int u,int v,int len,int time)
{
    e[tot].u=u; e[tot].v=v; e[tot].len=len; e[tot].time=time;
    g[u].push_back(tot++);
}

void SPFA(int s)
{
    queue<int>Q;
    memset(flag,0,sizeof flag);
    for(int i=0;i<=n;i++) Dis[i]=99999999;
    Q.push(s); flag[s]=1; Dis[s]=0;
    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[head]+e[id].len<Dis[e[id].v])
            {
                Dis[e[id].v]=Dis[head]+e[id].len;
                if(flag[e[id].v]==0)
                {
                    flag[e[id].v]=1;
                    Q.push(e[id].v);
                }
            }
        }
    }

    memset(flag,0,sizeof flag);
    for(int i=0;i<=n;i++) Tim[i]=99999999;
    Q.push(s); flag[s]=1; Tim[s]=0;
    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(Tim[head]+e[id].time<Tim[e[id].v])
            {
                Tim[e[id].v]=Tim[head]+e[id].time;
                if(flag[e[id].v]==0)
                {
                    flag[e[id].v]=1;
                    Q.push(e[id].v);
                }
            }
        }
    }
}

void dfs1(int x,int len,int time,int dep)
{
    if(len>ans_len) return;

    if(x==en)
    {
        if(len<ans_len)
        {
            ans_len=len;
            ans_time=time;
            ans_sz=dep;
            for(int i=0;i<dep;i++)
                ans_path[i]=path[i];
        }
        else if(len==ans_len)
        {
            if(time<ans_time)
            {
                ans_time=time;
                ans_sz=dep;
                for(int i=0;i<dep;i++)
                    ans_path[i]=path[i];
            }
        }
        return;
    }
    for(int i=0;i<g[x].size();i++)
    {
        int id=g[x][i];
        path[dep]=e[id].v;
        if(Dis[x]+e[id].len>Dis[e[id].v]) continue;
        dfs1(e[id].v,len+e[id].len,time+e[id].time,dep+1);
    }
}

void dfs2(int x,int time,int count,int dep)
{
    if(time>ans_time) return;

    if(x==en)
    {
        if(time<ans_time)
        {
            ans_time=time;
            ans_count=count;
            ans_sz=dep;
            for(int i=0;i<dep;i++)
                ans_path[i]=path[i];
        }
        else if(time==ans_time)
        {
            if(count<ans_count)
            {
                ans_count=count;
                ans_sz=dep;
                for(int i=0;i<dep;i++)
                    ans_path[i]=path[i];
            }
        }
        return;
    }
    for(int i=0;i<g[x].size();i++)
    {
        int id=g[x][i];
        path[dep]=e[id].v;
        if(Tim[x]+e[id].time>Tim[e[id].v]) continue;
        dfs2(e[id].v,time+e[id].time,count+1,dep+1);
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int u,v,f,len,time;
        scanf("%d%d%d%d%d",&u,&v,&f,&len,&time);
        addedge(u,v,len,time);
        if(f==0) addedge(v,u,len,time);
    }
    scanf("%d%d",&st,&en);

    SPFA(st);

    for(int i=0;i<=n;i++) flag[i]=9999999;
    ans_len=9999999;
    ans_time=9999999; flag[st]=0;
    dfs1(st,0,0,0);

    Distance = ans_len;
    p1.push_back(st);
    for(int i=0;i<ans_sz;i++) p1.push_back(ans_path[i]);

    for(int i=0;i<=n;i++) flag[i]=9999999;
    ans_time=9999999;
    ans_count=9999999; flag[st]=0;
    dfs2(st,0,0,0);

    Time=ans_time;
    p2.push_back(st);
    for(int i=0;i<ans_sz;i++) p2.push_back(ans_path[i]);

    bool fail=0;
    if(p1.size()!=p2.size()) fail=1;
    else {
        for(int i=0;i<p1.size();i++)
            if(p1[i]!=p2[i]) fail=1;
    }

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

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

    }
    return 0;
}
时间: 2024-10-17 18:37:20

PAT (Advanced Level) 1111. Online Map (30)的相关文章

PAT (Advanced Level) 1026. Table Tennis (30)

情况比较多的模拟题. 交了50发的样子才AC......AC之后我的天空星星都亮了. #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<map> #include<queue> #include<vector> using namespace std; struct

PAT (Advanced Level) 1080. Graduate Admission (30)

简单题. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<map> #include<stack> #include<queue> #include<string> #include<iostream> #include<algorithm> using namespace std;

PAT (Advanced Level) 1022. Digital Library (30)

简单模拟题. 写的时候注意一些小优化,小心TLE. #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<map> #include<queue> #include<vector> using namespace std; struct X { string id; c

PAT (Advanced Level) 1091. Acute Stroke (30)

BFS求连通块.递归会爆栈. #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<map> #include<queue> #include<stack> #include<vector> using namespace std; int M,N,L,T; int A[70][1300][133]; bo

PAT (Advanced Level) 1072. Gas Station (30)

枚举一下选的位置,每次算一下就可以了. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<map> #include<stack> #include<queue> #include<string> #include<algorithm> using namespace std; const int

PAT (Advanced Level) 1103. Integer Factorization (30)

暴力搜索. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<map> #include<queue> #include<stack> #include<algorithm> using namespace std; int n,k,p,top; int path[1000]; int flag=0; int

浙大 PAT Advanced level 1026. Table Tennis (30)

A table tennis club has N tables available to the public. The tables are numbered from 1 to N. For any pair of players, if there are some tables open when they arrive, they will be assigned to the available table with the smallest number. If all the

PAT (Advanced Level) 1004. Counting Leaves (30)

简单DFS. #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<vector> using namespace std; const int maxn=100+10; vector<int>g[maxn]; int n,m; int ans[maxn]; int root; i

PAT (Advanced Level) 1030. Travel Plan (30)

先处理出最短路上的边.变成一个DAG,然后在DAG上进行DFS. #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<queue> #include<vector> using namespace std; const int INF=0x7FFFFFFF; const int