最短路

这题题目如下:


9360. HIPERCIJEVI

Constraints

Time Limit: 4 secs, Memory Limit: 256 MB

Description

In a galaxy far, far away, the fastest method of transportation is using hypertubes. Each hypertube 

directly connects K stations with each other. What is the minimum number of stations that we need to 

pass through in order to get from station 1 to station N? 

Input

The first line of input contains three positive integers: N (1 ≤ ≤ 100 000), the number of stations, K 

(1 ≤ ≤ 1 000), the number of stations that any single hypertube directly interconnects, and M (1 ≤  ≤ 1 000), the number of hypertubes. 

Each of the following M lines contains the description of a single hypertube: K positive integers, the 

labels of stations connected to that hypertube. 

Output

The first and only line of output must contain the required minimum number of stations. If it isn't 

possible to travel from station 1 to station N, output -1. 

Sample Input

input 1:
9 3 5 
1 2 3 
1 4 5 
3 6 7 
5 6 7 
6 8 9

input 2:
15 8 4 
11 12 8 14 13 6 10 7 
1 5 8 12 13 6 2 4 
10 15 4 5 9 8 14 12 
11 12 14 3 5 6 1 13 

Sample Output

output 1:
4

output 2:
3
 
 
这题一开始我用的是Djistra但是邻接矩阵爆掉,存不了这么大,后来用spfa,但是还是用的邻接矩阵做的,还是RE了,最后不得不请教别人,
用的是vector来开二维数组,这样就不会爆掉了,还有一个人用邻接表来做的,速度更快,我就学了学邻接表。
 
邻接表代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int M=5001005;
const int N=101005;
const int inf=0x3f3f3f3f;
int dist[N],visit[N];
int n,k,m;
struct Edge
{
    int v,w,next;
    Edge(){}
    Edge(int V,int W,int NEXT):v(V),w(W),next(NEXT){}
}edge[M];
int size,head[N];


void init(){
    size=0;
    memset(head,-1,sizeof(head));
}


void Insertedge(int u,int v,int w)
{
    edge[size]=Edge(u,w,head[v]);
    head[v]=size++;
    edge[size]=Edge(v,w,head[u]);
    head[u]=size++;
}


void spfa(int st,int ed)
{
    queue<int>q;
    for(int i=1; i<=n+m; i++)
    {
        dist[i]=inf;
        visit[i]=0;
    }
    dist[1]=0;
    visit[1]=1;
    q.push(st);
    while(!q.empty())
    {
        int k=q.front();
        q.pop();
        visit[k]=0;
        for(int i=head[k]; i!=-1; i=edge[i].next)
        {
            int v=edge[i].v;
            if(dist[v]>dist[k]+edge[i].w)
            {
                dist[v]=dist[k]+edge[i].w;
                if(!visit[v])
                {
                    visit[v]=1;
                    q.push(v);
                }
            }
        }
    }
}


int main()
{
    int x;
    while(scanf("%d%d%d",&n,&k,&m)!=EOF)
    {
        init();
        for(int i=1; i<=m; i++)
        {
            for(int j=1; j<=k; j++)
            {
                scanf("%d",&x);
                Insertedge(x,i+n,1);
            }
        }
        spfa(1,n);
        if(dist[n]==inf)printf("-1\n");
        else printf("%d\n",dist[n]/2+1);
    }
    return 0;
}
 
vector 代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int N=100005;
int dist[N+1000];
vector<int>q[N+1000];
queue<int>p;
int n,k,m,ans,a;
int main()
{
    while(scanf("%d%d%d",&n,&k,&m)!=EOF)
    {
        for(int i=1; i<=m+n; i++)q[i].clear();
        for(int i=1; i<=m; i++)
        {
            for(int j=1; j<=k; j++)
            {
                scanf("%d",&a);
                q[i+n].push_back(a);
                 q[a].push_back(i+n);
                
            }
        }
          while(!p.empty()) p.pop();
        memset(dist,-1,sizeof(dist));
        dist[1]=0;
        ans=-1;
        p.push(1);
        while(!p.empty())
        {
            int k=p.front();
            p.pop();
            for(int i=0; i<q[k].size(); i++)
            {
                if(dist[q[k][i]]==-1)
                {
                    dist[q[k][i]]=dist[k]+1;
                    if(q[k][i]==n) ans=dist[n]/2+1;
                     p.push(q[k][i]);
                }
            }
            if(ans!=-1)break;
        }
        printf("%d\n",ans);
        
    }
    return 0;
}                                 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值