题解 CF229B 【Planets】

一道最短路,与模板不同的是这里多了一个判断条件:

当有其他人在使用这个星球的传送通道时,Jack无法离开这个星球。

最开始想到开一个二维数组存当前星球的传送门使用情况。

#include<bits/stdc++.h>
#define FOR(i,j,k)  for(int i=(j);i<=(k);i++)
using namespace std;
int n,m,cnt,Time;
int dis[100001];
bool inq[100001];
int h[100001],t[100001],nxt[100001],val[100001];
int used[100001][1001];
int f,e,q[1000001];
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
inline void addedge(int a,int b,int c)
{
	t[++cnt]=b,val[cnt]=c,nxt[cnt]=h[a],h[a]=cnt;
}
inline bool check(int Time,int planet)
{
    int i=0;
	while(used[planet][++i]!=0)
	{
		if(used[planet][i]==Time)	return true;
		if(used[planet][i]>Time)	return false;
	}
	return false;
}
int main()
{
	n=read(),m=read();
	memset(dis,-1,sizeof(dis));
    memset(h,0,sizeof(h));
    memset(inq,false,sizeof(inq));
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read(),w=read();
		addedge(u,v,w),addedge(v,u,w);
	}
	for(int i=1;i<=n;i++)
	{
		int tmp=read();
		for(int j=1;j<=tmp;j++)
			used[i][j]=read();
	}
	inq[1]=true,dis[1]=0,q[1]=1,f=e=1;
	while(f<=e)
	{
		int u=q[f++];
     		Time=dis[u];
      		while(check(Time,u))    Time++;
		for(int p=h[u];p;p=nxt[p])
		{
            int v=t[p],c=val[p];
			if(dis[v]==-1||dis[v]>=Time+c)
			{
                    dis[v]=Time+c;
                    if(!inq[v])	inq[v]=true,q[++e]=v;
            }
		}
		inq[u]=false;
	}
	printf("%d\n",dis[n]);
	return 0;
}

然后发现开不下,直接 \(MLE\)

于是想到 \(STL\)\(map\)

第一次写成这个样子,没过 \(#4\)

#include<bits/stdc++.h>
#define FOR(i,j,k)  for(int i=(j);i<=(k);i++)
using namespace std;
int n,m,cnt;
int dis[100001];
bool inq[100001];
int h[100001],t[100001],nxt[200001],val[200001];
int f,e,q[10000001];
map<int,int> s[100001];
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
inline void addedge(int a,int b,int c)
{
	t[++cnt]=b,val[cnt]=c,nxt[cnt]=h[a],h[a]=cnt;
}
inline bool check(int Time,int planet)
{
    int i=0;
	while(s[planet][++i]!=0)
	{
		if(s[planet][i]==Time)	return true;
		if(s[planet][i]>Time)	return false;
	}
	return false;
}
int main()
{
	n=read(),m=read();
	memset(dis,-1,sizeof(dis));
    memset(h,0,sizeof(h));
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read(),w=read();
		addedge(u,v,w),addedge(v,u,w);
	}
	for(int i=1;i<=n;i++)
	{
		int tmp=read();
		for(int j=1;j<=tmp;j++)
			s[i][j]=read();
	}
	inq[1]=true,dis[1]=0,q[1]=1,f=e=1;
	while(f<=e)
	{
		int u=q[f++];
        int Time=dis[u];
        while(check(Time,u))    Time++;
		for(int p=h[u];p;p=nxt[p])
		{
            int v=t[p],c=val[p];
			if(dis[v]==-1||dis[v]>=Time+c)
			{
                    dis[v]=Time+c;
                    if(!inq[v])	inq[v]=true,q[++e]=v;
            }
		}
		inq[u]=false;
	}
	printf("%d\n",dis[n]);
	return 0;
}

再换一种方法,把 \(map\) 改成 \(bool\) 的就过了

中间 \(t\) 数组开错大小一直没过。

#include<bits/stdc++.h>
#define FOR(i,j,k)  for(int i=(j);i<=(k);i++)
using namespace std;
int n,m,cnt;
int dis[100001];
bool inq[100001];
int h[100001],t[200001],nxt[200001],val[200001];
int f,e,q[10000001];
map<int,bool> s[100001];
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
inline void addedge(int a,int b,int c)
{
	t[++cnt]=b,val[cnt]=c,nxt[cnt]=h[a],h[a]=cnt;
}
int main()
{
	n=read(),m=read();
	memset(dis,-1,sizeof(dis));
    memset(h,0,sizeof(h));
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read(),w=read();
		addedge(u,v,w),addedge(v,u,w);
	}
	for(int i=1;i<=n;i++)
	{
		int tmp=read(),x;
		for(int j=1;j<=tmp;j++)
			x=read(),s[i][x]=true;
	}
	inq[1]=true,dis[1]=0,q[1]=1,f=e=1;
	while(f<=e)
	{
		int u=q[f++];
    	int Time=dis[u];
      while(s[u][Time]==true)    Time++;//唯一要注意的点
		for(int p=h[u];p;p=nxt[p])
		{
            int v=t[p],c=val[p];
			if(dis[v]==-1||dis[v]>=Time+c)
			{
                    dis[v]=Time+c;
                    if(!inq[v])	inq[v]=true,q[++e]=v;
            }
		}
		inq[u]=false;
	}
	printf("%d\n",dis[n]);
	return 0;
}

用的是 \(SPFA\)

posted @ 2020-08-08 21:27  LJC001151  阅读(72)  评论(0)    收藏  举报