TLE on #31的一点疑惑
查看原帖
TLE on #31的一点疑惑
340632
Cry_For_theMoon楼主2021/5/9 09:25

算法还是喜闻乐见的欧拉回路给边定向。

关于求欧拉回路,一开始我这样写

void Eular(int u){
	for(int j=first[u];j;j=next[j]){
		first[u]=next[j];
		if(edge[j].tag)continue;
		int v=edge[j].v;
		if(u<=2e5 && edge[j].w>0)ans[edge[j].w]=1;
		edge[j].tag=edge[op(j)].tag=1;
		Eular(v);
	}
}

就会 TLE on #31

但是稍微改了一下

void Eular(int u){
	for(int& j=first[u];j;j=next[j]){
		if(edge[j].tag)continue;
		int v=edge[j].v;
		if(u<=2e5 && edge[j].w>0)ans[edge[j].w]=1;
		edge[j].tag=edge[op(j)].tag=1;
		Eular(v);
	}
}

就是 AC

但是我认为这两种写法并没有本质区别啊,为什么运行速度会差两秒多。

TLE完整版:(只修改了Eular函数就AC了)

#include<bits/stdc++.h>
#define rep(i,a,b) for(ll i=(a);i<=(b);i++)
#define per(i,a,b) for(ll i=(a);i>=(b);i--)
#define op(x) ((x&1)?x+1:x-1)
#define odd(x) (x&1)
#define even(x) (!odd(x))
#define lc(x) (x<<1)
#define rc(x) (lc(x)|1)
#define lowbit(x) (x&-x)
#define Max(a,b) (a>b?a:b)
#define Min(a,b) (a<b?a:b)
#define next Cry_For_theMoon
#define il inline
#define pb(x) push_back(x)
#define is(x) insert(x)
#define sit set<int>::iterator
#define mapit map<int,int>::iterator
#define pi pair<int,int>
#define ppi pair<int,pi>
#define pp pair<pi,pi>
#define fr first
#define se second
#define vit vector<int>::iterator
#define C(x) (x+200000)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef double db;
using namespace std;
const int MAXN=1e6+10,MAXM=2e6+10;
struct Edge{
	int u,v,w,tag;
}edge[MAXM];
int first[MAXN],next[MAXM],tot;
int n,m,x[MAXN],y[MAXN];
int size[MAXN],vis[MAXN];
vector<int>V;
int ans[MAXN];
void addedge(int u,int v,int w){
	edge[++tot]=(Edge){u,v,w,0};next[tot]=first[u];first[u]=tot;
}
int alone(int i){return !size[i];} 
void dfs(int u){
	vis[u]=1;V.pb(u);
	for(int j=first[u];j;j=next[j]){
		int v=edge[j].v;
		if(vis[v])continue;
		dfs(v);
	}
}
void Eular(int u){
	for(int j=first[u];j;j=next[j]){
		first[u]=next[j];
		if(edge[j].tag)continue;
		int v=edge[j].v;
		if(u<=2e5 && edge[j].w>0)ans[edge[j].w]=1;
		edge[j].tag=edge[op(j)].tag=1;
		Eular(v);
	}
}
void solve(){
	int pre=0;
	for(vit it=V.begin();it!=V.end();it++){
		int v=*it;
		if(even(size[v]))continue;
		if(!pre){
			pre=v;
		}else{
			addedge(v,pre,-1),addedge(pre,v,-1);
			pre=0; 
		}
	}
	Eular(V[0]);
} 
int main(){
	n=4e5;
	cin>>m;
	rep(i,1,m){
		cin>>x[i]>>y[i];addedge(x[i],C(y[i]),i);addedge(C(y[i]),x[i],i);
		size[x[i]]++;size[C(y[i])]++;
	}
	rep(i,1,n){
		if(alone(i))continue;
		if(vis[i])continue;
		V.clear();
		dfs(i);
		solve();
	}
	rep(i,1,m){
		if(ans[i])printf("r");
		else printf("b");
	}
	return 0;
}

2021/5/9 09:25
加载中...