社区讨论
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 条回复,欢迎继续交流。
正在加载回复...