基环树删边,又W又T
查看原帖
基环树删边,又W又T
205782
R浩轩泽Anmicius楼主2021/10/6 16:23

原本觉得这道题比较水来着...但不知道为什么WA了几个点,最后四个点还超时了

大佬能帮忙看看嘛)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=5e4,inf=0x7fffffff;
int n,m,num,ber,head[N],in[N],st=inf;
bool vis[N],ban[N];//ban是本次删掉的边
queue<int>q;
struct Edge{
	int from;
	int to;
	int nxt;
}edge[N];
struct Ans{
	int ans[N];
	Ans(){memset(ans,0x3f,sizeof ans);}
	bool operator<(const Ans &b)const{
		for(int i=1;i<=n;++i)
		if(this->ans[i]!=b.ans[i])
		return this->ans[i]<b.ans[i];
	}
	Ans operator=(const Ans &b){
		for(int i=1;i<=n;++i)
		this->ans[i]=b.ans[i];
		return *this;
	}
}res,cnt;//res即最终答案,cnt是单次删边后的答案
void init(){
	memset(vis,false,sizeof vis);
	ber=0;
	for(int i=1;i<=n;++i)
	res.ans[i]=inf;
}
inline void add_edge(int x,int y){
	edge[++num].from=x;
	edge[num].to=y;
	edge[num].nxt=head[x];
	head[x]=num;
}
void dfs(int x){
	priority_queue< int,vector<int>,greater<int> >q;
	res.ans[++ber]=x;
	for(int i=head[x];i;i=edge[i].nxt){
		int v=edge[i].to;
		if(!vis[v]&&!ban[i]){
			q.push(v);
			vis[v]=true;
		}
	}
	while(!q.empty()){
		int u=q.top();q.pop();
		dfs(u);
	}
}
inline void read(int &x){
	x=0;int f=1;char ch=getchar();
	while(!isdigit(ch)){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(isdigit(ch)){
		x=x*10+(ch^48);
		ch=getchar();
	}
	x*=f;
}
signed main(){
	//freopen("travel.in","r",stdin);
	//freopen("travel.out","w",stdout);
	read(n);read(m);
	for(int i=1;i<=m;++i){
		int x,y;
		read(x);read(y);
		st=min(st,x);
		st=min(st,y);
		add_edge(x,y);
		add_edge(y,x);
		++in[x];++in[y];
	}
	for(int i=1;i<=n;++i)
	if(in[i]==1)q.push(i);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=head[u];i;i=edge[i].nxt){
			int v=edge[i].to;
			--in[v];
			if(in[v]==1)
			q.push(v);
		}
	}
	if(n>m){
		vis[st]=true;
		dfs(st);
		cnt=res;
	}
	else {
		for(int i=1;i<=m;++i){
			init();
			if(in[edge[i].from]>1&&in[edge[i].to]>1)
			ban[i]=true;
			vis[st]=true;
			dfs(st);
			ban[i]=false;
			if(res<cnt)cnt=res;
		}
	}
	for(int i=1;i<=n;++i)
	printf("%d ",cnt.ans[i]);
	return 0;
}
2021/10/6 16:23
加载中...