这题题目如下:
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 ≤ N ≤ 100 000), the number of stations, K
(1 ≤ K ≤ 1 000), the number of stations that any single hypertube directly interconnects, and M (1 ≤ M ≤ 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; }