D - .. (Double Dots)(贪心&最短路)

D - … (Double Dots)(贪心&最短路)

传送门

思路:一开始以为是单源最短路水题,每次更新储存下相邻的结点即可,这种做法能AC,但是复杂了。

后来看了别人写的,跟最短路没什么关系,因为题目保证是个连通图,所以必有答案,又因为相连的点距离恒为1,所以贪心即可,与1相连的点的答案必定是1,然后不断向外扩散即可。。

s p f a spfa 做法:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,inf=0x3f3f3f3f;
#define mst(a) memset(a,0,sizeof a)
int n,d[N],vis[N],sign[N],m;
vector<int>e[N<<1];
void spfa(){
	queue<int>q;
	for(int i=1;i<=n;i++) d[i]=inf;
	q.push(1);vis[1]=1,d[1]=0;
	while(q.size()){
		int u=q.front();q.pop();vis[u]=0;
		for(auto v:e[u]){
			if(d[v]>d[u]+1){
				d[v]=d[u]+1;
				sign[v]=u;
				if(!vis[v]) q.push(v),vis[v]=1; 
			}
		}
	}
	int ok=0;
	for(int i=2;i<=n;i++) 
	if(d[i]==inf){
		 ok=1;
		 break;
	}
	if(ok) puts("No");
	else {
		puts("Yes");
		for(int i=2;i<=n;i++)
			printf("%d\n",sign[i]);
	}
} 
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u); 
	} 
	spfa();
	return 0;
} 

贪心做法:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
#define mst(a) memset(a,0,sizeof a)
vector<int>e[N];
int n,m,ans[N];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&u,&v);
		e[u].push_back(v),e[v].push_back(u);
	}
	ans[1]=1;
	queue<int>q;
	q.push(1);
	while(q.size()){
		int u=q.front();q.pop();
		for(auto v:e[u])
			if(!ans[v]) ans[v]=u,q.push(v); 
	}
	puts("Yes");
	for(int i=2;i<=n;i++) printf("%d\n",ans[i]);
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/106191249
今日推荐