标签:欧拉路 情况 ret while include log memset lap font
纯dfs,但是由于按大部分板子上dfs,会导致某个点已经dfs过一部分边,但在其他层dfs时又会再次访问这些vis过的边,虽然不进行递归,但是仍然需要for循环过去判断vis,因此极限情况仍然比O(n+m)大很多,亲测cf508D上38组样例卡掉,46ms到2s T掉的差距。不过由于某条边访问过之后一定不会再访问,所以可以直接删去那条边,修改head值就行,这样就能做到O(n+m),额……大概吧
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
const int maxn=1005; //点数
const int maxm=1005*26; //边数
int head[maxn],size;
int point[maxm],nxt[maxm],vis[maxm],ind[maxm];
int id[maxn],od[maxn];
int cnt;
int ans[maxm];
void init(){
cnt=size=0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(id,0,sizeof(id));
memset(od,0,sizeof(od));
}
void adde(int a,int b,int index){
point[size]=b;
ind[size]=index;
nxt[size]=head[a];
head[a]=size++;
od[a]++;id[b]++;
}
void dfs(int s){
for(int i=head[s];~i;i=nxt[i]){
if(!vis[i]){
vis[i]=1;
dfs(point[i]);
ans[cnt++]=ind[i];
}
}
}
//边数较多的图中可能重复遍历已经访问过的边会T,访问一条边直接删一条边可以更加快速
/*
void dfs(int s){
while(~head[s]){
int i=head[s];
head[s]=nxt[i];
dfs(point[i]);
ans[cnt++]=ind[i];
}
}
*/
void solve(int n,int m){ //n点m边
int c1=0,c2=0,stx=1; //stx取标号最小的节点
for(int i=1;i<=n;i++){
if(od[i]-id[i]==1)c1++,stx=i;
else if(od[i]-id[i]==-1)c2++;
else if(od[i]-id[i]!=0)c1=3;
}
if(!((c1==0&&c2==0)||(c1==1&&c2==1))){
printf("NO\n");
return;
}
dfs(stx);
if(cnt!=m){
printf("NO\n");
return;
}
printf("YES\n");
for(int i=cnt-1;i>=0;--i){
printf("%d ",ans[i]);
}
printf("\n");
}
标签:欧拉路 情况 ret while include log memset lap font
原文地址:http://www.cnblogs.com/cenariusxz/p/6006331.html