社区讨论

7个MLE,求调

P5022[NOIP 2018 提高组] 旅行参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lov4t9k1
此快照首次捕获于
2023/11/12 15:05
2 年前
此快照最后确认于
2023/11/12 16:35
2 年前
查看原帖
我大抵是这道题为数不多能写出MLE的人了
思路:存边,排序,普通树dfs。基环树先bfs找环,再dfs把环上各点的顺序用lop记录,再一个个删边,dfs,用check()判断是否更优,res[]为当前图的路径,ans[]是答案
下面是代码,求调
CPP
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#define pii pair<int,int>
using namespace std;
void add(int,int);//恢复被删边 
void delte(int,int);//删边 
void dfs(int,int);//按照环的节点顺序遍历,记录节点 
void bfs();//去掉非环节点 

const int N=5000+10;
int n,m;
int t;
int pos[N],ans[N],res[N],du[N];
int bo=0,cnt;

vector<int> edge[N],lop; 

void dfs1(int u,int from)//树 
{
	printf("%d ",u);
	int len=edge[u].size();
	for(int i=0;i<len;++i)
	{
		int v=edge[u][i];
		if(v!=from && v!=0)
			dfs1(v,u);
	}
}

void dfs2(int u,int from)//基环树,和dfs1的唯一区别是第一行
{
	res[cnt++]=u;
	int len=edge[u].size();
	for(int i=0;i<len;++i)
	{
		int v=edge[u][i];
		if(v!=from && v!=0)
			dfs2(v,u);
	}
}

bool check()
{
	for(int i=0;i<n;++i)
	{
		if(res[i]<ans[i])return true;
		else if(res[i]>ans[i])return false;
	}
}

int main()
{
//	freopen("travel.in","r",stdin);
//	freopen("travel.out","w",stdout);
	cin>>n>>m;
	for(int i=1,u,v;i<=m;++i)
	{
		scanf("%d%d",&u,&v);
		edge[u].push_back(v);
		edge[v].push_back(u);
		du[u]++;du[v]++;
	}
	for(int i=1;i<=n;++i)sort(edge[i].begin(),edge[i].end());
	
	if(m==n-1)dfs1(1,0);
	else
	{
		bfs();
		for(int i=1;i<=n;++i)if(du[i]!=0){t=i;break;}dfs(t,0);
		
		memset(ans,0x3f,sizeof(ans));
		for(int i=0;i<lop.size();++i)
		{
			memset(res,0x3f,sizeof(res));
			
			int u=i,v=(u+1)%lop.size();
			if(u==0)delte(lop[u],lop[v]);
			else{add(lop[u-1],lop[u]);delte(lop[u],lop[v]);}
			
			cnt=bo=0;
			dfs2(1,0);
			if(check())for(int i=0;i<n;++i)ans[i]=res[i];
		}
		for(int i=0;i<n;++i)printf("%d ",ans[i]);
	}
//	fclose(stdin);
//	fclose(stdout);
	return 0;
}



void add(int u,int v)
{
	for(int i=0;i<edge[u].size();++i)if(edge[u][i]==0)edge[u][i]=v;
	for(int i=0;i<edge[v].size();++i)if(edge[v][i]==0)edge[v][i]=u;
}

void delte(int u,int v)
{
	for(int i=0;i<edge[u].size();++i)if(edge[u][i]==v)edge[u][i]=0;
	for(int i=0;i<edge[v].size();++i)if(edge[v][i]==u)edge[v][i]=0;
}
void dfs(int u,int from)
{
	for(int i=0;i<edge[u].size();++i)
	{
		int v=edge[u][i];
		if(v!=from && du[v]!=0)
		{
			lop.push_back(v);du[v]--;du[u]--;
			dfs(v,u);
		}
	}
}

void bfs()
{
	queue<int> q;
	for(int i=1;i<=n;++i)if(du[i]==1)q.push(i);
	while(!q.empty())
	{
		int u=q.front();q.pop();
		for(int i=0;i<edge[u].size();++i)
		{
			int v=edge[u][i];
			du[v]--;du[u]--;
			if(du[v]==1)q.push(v);
		}
	}
}



回复

0 条回复,欢迎继续交流。

正在加载回复...