Time Limit: 3000MS | Memory Limit: 65536K | |||
Total Submissions: 5902 | Accepted: 2538 | Special Judge |
Description
Input
Output
Sample Input
4 5 1 2 1 4 2 3 2 4 3 4
Sample Output
1 2 3 4 2 1 4 3 2 4 1
分析:
其实我们不能死瞄着dfs一直深搜,这样就很难想通了,我们可以想想,欧拉图的节点的度的问题,(我这里就专门讨论有向图,无向图可以转换成有向图做的),假设节点s为起点,则深搜到不能搜的时候那个节点就是s。为什么呢,只要将这点想通,基本就没什么问题了。
我们知道如果一个节点入度减1,那么它的出度必然要减1,在以s为起点的路径中,se1v1e2v2....eivi,如果vi节点
不是s节点且为深搜的最后节点,也就是说vi没有了出度,然而我们知道对于v1...v(i-1)节点入度一但减少,出度也就减少了,然而对于s起点来说只要出度减少却没有入度减少,vi的入度减少却没有了出度,所以证明vi节点不可能会成为不是s节点且为深搜的最后节点,即除非他还不是深搜的最后节点,到这里我们基本就可以确定了,vi要满足深搜最后节点必然为vi==s,这样的话vi的入度减少了,出度也减少了(因为s出度减少了),s的出度减少了,入度也减少了(因为vi的入度减少了)所以可以证明以s为起点的深搜最后节点也为s。
哎呀,说的有点累了,不知道大家明白没。
然后就是返回了,当沿着路径返回的途中如果vi节点还有出度的话,那么就以vi为起点开始深搜,根据上面的证明,我们可以知道最后的深搜节点肯定为vi起点了。
现在大概知道我要最后说什么了吧,将回路se1v1e2v2.....eivi(ei1vi1ei2vi2...eiivi)e(i+1).....ejs,括号里面的就是返回途中发生的又一次回路咯,把它嵌入到里面自然大的回路也满足要求了。
#include"stdio.h" #include"string.h" #include"queue" #include"stack" #include"iostream" #include"string" #include"map" #include"stdlib.h" #define inf 99999999 #define M 10009 using namespace std; struct node { int u,v,next; }edge[M*15]; int t,head[M],use[M*15],s[M*15],cnt,Stack[M*15],m; void init() { t=0; memset(head,-1,sizeof(head)); } void add(int u,int v) { edge[t].u=u; edge[t].v=v; edge[t].next=head[u]; head[u]=t++; } void DFS(int u) { for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(!use[i]) { use[i]=1; DFS(v); } } printf("%d\n",u); } int main() { int n,i; while(scanf("%d%d",&n,&m)!=-1) { init(); for(i=1;i<=m;i++) { int a,b; scanf("%d%d",&a,&b); add(a,b); add(b,a); } memset(use,0,sizeof(use)); DFS(1); } }