Codeforces 508D Tanya and Password
这个题类似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; }