这个题类似poj1780 也是欧拉路的题目 于是类似那个写了一个 发现t了
原因就是有一组数据
200000
zzz
zzz
zzz
...
zzz
这样是一个点 200000个边
而第i层的dfs 都访问了200000-i次边
因为第一层 从第一条开始 发现没有被标记过 顺着第一条走到第一个点 开始第二层
一直到第200000层 都是这样
然后 200000层发现没有没标记过的边了 返回第199999层之后 199999层会继续遍历已经标记过的后面的边
一直到第一层 还会便利已经被标记过的第二条到第200000条边 所以会超时
#include<bits/stdc++.h>
using namespace std;
struct self
{
int x,y,nxt;
}s[1000001];
int fst[1000001];
int h(char* str)
{
int ret = str[0]*1000+str[1];
return ret;
}
int g[999999];
int tot;
int outd[1000001],ind[1000001];
int m,n,x,y;
char str[4],l[4],r[4];
int ret[1000001],ans;
char old[1000001][4];
int pos,num;
int flag[1000001];
int ceng;
void dfs(int u)
{
//for(int i=fst[u];i!=-1;i=s[i].nxt)
for(int i=fst[u];i!=-1;i=fst[u])
{
if(!flag[i])
{
flag[i]=1;
//
fst[u]=s[i].nxt;
dfs(s[i].y);
ret[++ans]=i;
}
}
}
void print()
{
if(ans<m)
printf("NO\n");
else
{
printf("YES\n");
printf("%c",old[s[ret[ans]].x][0]);
printf("%c",old[s[ret[ans]].x][1]);
for(int i=ans;i>=1;i--)
printf("%c",old[s[ret[i]].y][1]);
}
}
int main()
{
memset(fst,-1,sizeof(fst));
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%s",str);
l[0]=str[0];l[1]=str[1];
r[0]=str[1];r[1]=str[2];
if(!g[h(l)])
{
g[h(l)]=++tot;
old[tot][0]=l[0];
old[tot][1]=l[1];
}
if(!g[h(r)])
{
g[h(r)]=++tot;
old[tot][0]=r[0];
old[tot][1]=r[1];
}
outd[g[h(l)]]++;
ind[g[h(r)]]++;
n++;
s[n].x=g[h(l)];
s[n].y=g[h(r)];
s[n].nxt=fst[g[h(l)]];
fst[g[h(l)]]=n;
}
pos=1;
int ok=1;
for(int i=1;i<=tot;i++)
{
if(outd[i]!=ind[i])
num++;
if(outd[i]==ind[i]+1)
pos=i;
if(outd[i]>ind[i]+1 || outd[i]<ind[i]-1)
ok=0;
}
if(!ok)
{
printf("NO\n");
return 0;
}
if(num!=0 && num!=2)
{
printf("NO\n");
return 0;
}
dfs(pos);
print();
}
原来遍历边都是采用这样的方法 就是邻接表的遍历方法
恩看来要灵活运用啊!
for(int i=fst[u];i!=-1;i=s[i].nxt)
if(!flag[i])
{
flag[i]=1;
dfs(s[i].y);
ans++;
ret[ans]=i;
}