PAT甲级题解 1131 DFS

遇到数据处理比较困难的就先处理数据 把它映射到相应的数据结构里面 这里把两个站点之和映射到line指定的线上 然后每次遍历路径的时候计算出有多少次换乘以后再和最大的进行比较 说起来难度不大 但是如果要上手的话应该就不一样了 还得自己再多写几遍才行

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 10010;
vector<int> G[MAXN];
unordered_map<int,int> line;
int vis[MAXN],minCnt,minTransfer,start,end1;
vector<int> path,tempPath;
int tansferCnt(vector<int> a)
{
    int cnt = -1;//要是一直相等就加了一次等于0 说明没有换乘
    int preline = 0;
    for(int i = 1;i<a.size();i++)//计算这条路径上有换乘了几次  只要比较前一个和后一个是否线路相等
    {
        if(line[a[i - 1] * 10000 + a[i]] != preline)
        {
            cnt++;
        }
        preline = line[a[i - 1] * 10000 + a[i]];
    }
    return cnt;
}
void DFS(int node,int cnt)
{
    if(node == end1 && (cnt < minCnt || (cnt == minCnt && tansferCnt(tempPath) < minTransfer)))
    {
        minCnt = cnt;
        minTransfer = tansferCnt(tempPath);
        path = tempPath;
    }
    if(node == end1)
    {
        return ;
    }
    for(int i = 0;i<G[node].size();i++)
    {
        if(vis[G[node][i]] == false)
        {
            vis[G[node][i]] = true;
            tempPath.push_back(G[node][i]);
            DFS(G[node][i],cnt + 1);
            vis[G[node][i]] = false;
            tempPath.pop_back();
        }
    }
}
int main(void)
{
    freopen("pat0314/in.txt","r",stdin);
    int n,m,k,pre,temp;
    scanf("%d",&n);
    for(int i = 0;i<n;i++)
    {
        scanf("%d %d",&m,&pre);
        for(int j = 1;j<m;j++)
        {
            scanf("%d",&temp);
            G[pre].push_back(temp);
            G[temp].push_back(pre);
            line[pre * 10000 + temp] = line[temp * 10000 + pre] = i + 1;
            pre = temp;
        }
    }
    scanf("%d",&k);
    for(int i = 0;i<k;i++)
    {
        scanf("%d %d",&start,&end1);
        minCnt = 999999;
        minTransfer = 999999;
        tempPath.clear();
        tempPath.push_back(start);
        vis[start] = 1;
        DFS(start,0);
        vis[start] = 0;
        printf("%d\n",minCnt);
        int preline = 0;
        int pretransfer = start;
        for(int j = 1;j < path.size();j++)
        {
            if(line[path[j - 1] * 10000 + path[j]] != preline)
            {
                if(preline != 0)
                {
                    printf("Take Line#%d from %04d to %04d.\n",preline,pretransfer,path[j - 1]);
                }
                preline = line[path[j - 1] * 10000 + path[j]];
                pretransfer = path[j - 1];
            }
        }
        printf("Take Line#%d from %04d to %04d.\n",preline,pretransfer,end1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值