Kattis-torn to pieces

本文介绍了一种利用最短路径算法解决地图碎片拼接问题的方法。通过将地图碎片上的节点映射为图中的顶点,并建立连接关系,实现了查询两点间是否能通过拼接的地图碎片连通的功能。文章详细解释了算法实现过程及调试经验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:第一行给出n代表有n张地图碎片,接下来n行给出碎片上的信息,第一个单词代表这个碎片上的节点,后边所有的节点都与第一个节点相连接.

最后一行给出查询,问从A到B是否存在一条路径可以通过给定的拼图的一部分拼凑而成,可行的话输出路径,否则输出no route find

可能是比赛当时受了先前题目的影响,看到这题之后第一时间想到的就是最短路,题目保证了最多只有一条路.因此,只需要把每个节点名字一一对应成id,id对应节点,然后跑一次最短路,然后找出那条路径即可.

其中有一个数据一直没过:因为映射的时候id从0开始标记,而默认的map影射也是从0开始的,如果id从1开始可以自动避过这个坑.

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
int n;
int cnt;
map<string,int>m;
map<int,string> mm;
vector<string>v;
string s;
int vis[5000],dis[5000],pre[5000];
int G[5000][5000];
void init()
{
    m.clear();
    mm.clear();
     for(int i=0;i<5000;i++){
        for(int j=0;j<5000;j++){
            if(i==j)G[i][j]=0;
            else G[i][j]=inf;
        }
    }
    memset(dis,inf,sizeof(dis));
    memset(vis,0,sizeof(vis));
    memset(pre,-1,sizeof(pre));
    cnt=0;
    getline(cin,s);
    for(int i=0; i<n; i++)
    {
        v.clear();
        getline(cin,s);
        string temp = "";
        for(int i=0; i<s.size(); i++)
        {
            if(s[i]==' ')
            {
                v.push_back(temp);
                temp="";
                continue;
            }
            else temp+=s[i];
        }
        v.push_back(temp);

        for(int i=0;i<v.size();i++){
            if(m.count(v[i])==0){
                m[v[i]]=cnt;
                mm[cnt]=v[i];
                cnt++;
            }
        }
        //cout<<m[v[0]]<<endl;
        for(int i=1;i<v.size();i++)
            G[m[v[0]]][m[v[i]]]=G[m[v[i]]][m[v[0]]]=1;
    }
//    for(int i=0;i<cnt;i++){
//        for(int j=0;j<cnt;j++){
//            cout<<G[i][j]<<" ";
//        }
//        cout<<endl;
//    }
}

void dij(int st){
    dis[st]=0;
    vis[st]=1;

    for(int i=0; i<cnt; i++)
    {
        int minnum=inf,next=st;
        for(int j=0; j<cnt; j++)
        {
            if(vis[j]==0&&minnum>dis[j])
            {
                minnum=dis[j];
                next=j;
            }
        }
        vis[next]=1;
        for(int j=0; j<cnt; j++)
        {
            if(vis[j]==0)
            {
                if(dis[j]>dis[next]+G[next][j])
                {
                    dis[j]=dis[next]+G[next][j];
                    pre[j]=next;
                }
            }
        }
    }
}
void path(int ed)
{
    if(pre[ed]!=-1)
    {
        path(pre[ed]);
        cout<<mm[pre[ed]]<<" ";
    }
}

int main()
{
   //freopen("1.txt", "r", stdin);
    std::ios::sync_with_stdio(false);
    cin>>n;
    init();
    string sst,sed;
    cin>>sst>>sed;
    if(m.count(sst)==0||m.count(sed)==0){
        cout<<"no route found"<<endl;
        return 0;
    }
    dij(m[sst]);
    //cout<<dis[m[sed]]<<endl;
    if(dis[m[sed]]==inf)
        cout<<"no route found"<<endl;
    else {
        path(m[sed]);
        cout<<mm[m[sed]];
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值