Time Limit: 3000MS | Memory Limit: 65536K | |||
Total Submissions: 5902 | Accepted: 2538 | Special Judge |
Description
If she were a more observant cow, she might be able to just walk each of M (1 <= M <= 50,000) bidirectional trails numbered 1..M between N (2 <= N <= 10,000) fields numbered 1..N on the farm once and be confident that she's seen everything she needs to see. But since she isn't, she wants to make sure she walks down each trail exactly twice. It's also important that her two trips along each trail be in opposite directions, so that she doesn't miss the same thing twice.
A pair of fields might be connected by more than one trail. Find a path that Bessie can follow which will meet her requirements. Such a path is guaranteed to exist.
Input
* Lines 2..M+1: Two integers denoting a pair of fields connected by a path.
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); } }