PAT (Advanced Level) Practice 1131 Subway Map (30 分)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Nightmare_ak/article/details/84886776

嘤嘤嘤,有点难打啊- =,暴力跑最短路,Dijsktra应该不行,因为先出队列的不一定最优。

#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
using namespace std;

typedef long long ll;

const int N=10000;
const int INF=0x3f3f3f3f;

struct Edge
{
    int v,w,next;
}edge[N*N];

int st,ed,vis[N],head[N],edgetot,mincost,mindis,cnt;
vector<int> res,now;
map<int,int> mp,rmp;
map<ll,int> color;

void dfs(int u,int dis,int cost,int pre)
{
    vis[u]=1,now.push_back(u);
    if(u==ed)
    {
        if(dis<mindis||dis==mindis&&cost<mincost)
            mindis=dis,mincost=cost,res=now;
        vis[u]=0,now.pop_back();
        return;
    }
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v,w=(edge[i].w!=pre);
        if(vis[v]) continue;
        dfs(v,dis+1,cost+w,edge[i].w);
    }
    vis[u]=0,now.pop_back();
}

void addEdge(int u,int v,int w)
{
    edge[edgetot]={v,w,head[u]};
    head[u]=edgetot++;
}

int main()
{
    edgetot=0,cnt=0;
    memset(head,-1,sizeof(head));
    int n;scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int k;scanf("%d",&k);
        int u;
        for(int j=1;j<=k;j++)
        {
            int v;scanf("%d",&v);
            if(!mp.count(v)) mp[v]=++cnt,rmp[cnt]=v;
            v=mp[v];
            if(j!=1)
            {
                addEdge(u,v,i),addEdge(v,u,i);
                color[u*N+v]=color[v*N+u]=i;
            }
            u=v;
        }
    }
    int q;scanf("%d",&q);
    while(q--)
    {
        scanf("%d%d",&st,&ed);
        st=mp[st],ed=mp[ed];
        mincost=mindis=INF;
        dfs(st,0,0,0);
        printf("%d\n",mindis);
        int pre=color[res[0]*N+res[1]],pnode=res[0];
        for(int i=1;i<res.size();i++)
        {
            if(color[res[i-1]*N+res[i]]!=pre)
            {
                printf("Take Line#%d from %04d to %04d.\n",pre,rmp[pnode],rmp[res[i-1]]);
                pre=color[res[i-1]*N+res[i]],pnode=res[i-1];
            }
        }
        printf("Take Line#%d from %04d to %04d.\n",pre,rmp[pnode],rmp[ed]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Nightmare_ak/article/details/84886776