POJ 2230 Watchcow 欧拉路径 DFS

来源:互联网 发布:重庆大学软件下载 编辑:程序博客网 时间:2024/05/18 01:51

题目描述:

Bessie's been appointed the new watch-cow for the farm. Every night, it's her job to walk across the farm and make sure that no evildoers are doing any evil. She begins at the barn, makes her patrol, and then returns to the barn when she's done. 

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:

* Line 1: Two integers, N and M. 

* Lines 2..M+1: Two integers denoting a pair of fields connected by a path.


因为是一条边来回2次,且方向不同。等同于将求欧拉的有向图问题。 欧拉有向图存在的两个条件:1、图是连通的,2、每个点入度跟出度相同。很显然第2点是正确的,又由题目中的保证,任意两点存在路,所以不用进行欧拉判定了。直接输出路径就OK了。

欧拉回路的最大特点是存在环,记现在找到的为路径1,现在假设起点为v0,也就是说现在找到了一条路径,从vo走过了图中的一些边又回到了v0,而且没走过的那些点一定会形成一个一个的环。 这些环会被这些点的祖宗之后遍历。所以只用保证祖宗在这些环后输出,即能得到一个正确的算法。

            不过此算法O(m)时间复杂度,可能因为DFS用函数实现。。在数据量大时,效率不高。。唉。。好佩服那些0MS AC的神牛啊。。

     

/** * 因为是给的是无向图的结构,转化成有向图做,所以必定存在回路 * 而且题目保证了回路的存在 * @author ipqhjjybj * @date 20130627 */#include <cstdio>#include <cmath>#include <cstdlib>#include <ctime>#include <iostream>#include <cmath>#include <algorithm>#include <numeric>#include <utility>#include <cstring>#include <vector>#include <stack>#include <queue>#include <map>#include <string>using namespace std;#define inf 0x3f3f3f3f#define MAXN 10005#define MAXM 50010#define clr(x,k) memset((x),(k),sizeof(x))#define cpy(x,k) memcpy((x),(k),sizeof(x))#define Base 10000typedef vector<int> vi;typedef stack<int> si;typedef vector<string> vs;#define sz(a) int((a).size())#define pb push_back#define all(c) (c).begin(),(c).end()#define rep(i,n) for(int i = 0;i < n;++i)#define foreach(it,c) for(vi::iterator it = (c).begin();it != (c).end();++it)#define max(a,b) ((a)>(b)?(a):(b))#define min(a,b) ((a)<(b)?(a):(b))struct node{    int next,to;}edges[MAXM<<1];int box[MAXN],n,m,tot;bool visit[MAXM<<1];void add(int a,int b){ // 链式前向星存储边    edges[tot].to=b;    edges[tot].next=box[a];    box[a]=tot++;}void init(){    clr(edges,0);clr(box,-1);    tot=2;    for(int i = 0,a,b;i < m;i++){        scanf("%d %d",&a,&b);        add(a,b),add(b,a);    }    clr(visit,false);}void DFS(int now){    int k;    for(k = box[now];k!=-1;k=edges[k].next){        if(!visit[k]){            visit[k]=true;  //标记当前边            DFS(edges[k].to);            //ans[ansi++]=edges[k].to;  //回溯过程记录经过的点            printf("%d\n",edges[k].to);        }    }}int main(){    //freopen("2230.in","r",stdin);    scanf("%d %d",&n,&m);        init();        DFS(1);        printf("1\n"); //最终回到了1这个点    return 0;}

原创粉丝点击