您的位置:首页 > 其它

POJ 1041 John's trip(欧拉回路)

2015-09-02 19:03 393 查看
题意:给出两个点所构成的一条边 点和边各有各的计数规则,已知所给的图是连通图,求能否从起点出发,每条边经过切只经过一次再次回到原点,若不能输出错误信息,若能输出可能存在的路径的最小字典序。

解题思路:

题目已经明确所给的图是连通图,所以不用在判断图的连通性了。先判断是否存在欧拉回路,若有度数为奇数的点则不存在。可以使用链式向前星存图,边的编号可以想象成类似于权值,要求输出的字典序最小,所以在dfs尝试回溯构建欧拉回路的时候,应该优先尝试权值小的点,所以要对读入的关系,先进行排序。最后判断就好了。

模板:

void dfs(int now)
{
    for(int k = head[now] ; k != -1 ; k = edge[k].next)
    {
        if(!vis[k])
        {
            vis[k] = true;
            vis[k^1] = true;
            dfs(edge[k].to);
            ans[iq++] = k;

        }
    }
}


比较悲哀的是,算法的思路很正确, 有一点细节没处理好, 导致WA了几次。

WA的dfs代码:警示自己

void dfs(int now)
{
    for(int k = head[now] ; k != -1 ; k = edge[k].next)
    {
        if(!vis[k])
        {
            vis[k] = true;
            vis[k^1] = true;
            dfs(edge[k].to);
            ans[iq++] = edge[k].way;
        }
    }
}


最后的AC代码

Memory: 840 KBTime: 32 MS
Language: G++Result: Accepted
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<list>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>

using namespace std;

#define FOR(i, s, t) for(int i = (s) ; i <= (t) ; ++i)
#define REP(i, n) for(int i = 0 ; i < (n) ; ++i)

int buf[10];
inline long long read()
{
    long long x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}

inline void writenum(int i)
{
    int p = 0;
    if(i == 0) p++;
    else while(i)
        {
            buf[p++] = i % 10;
            i /= 10;
        }
    for(int j = p - 1 ; j >= 0 ; --j) putchar('0' + buf[j]);
}
/**************************************************************/
#define MAX_N 2005
const int INF = 0x3f3f3f3f;
bool vis[MAX_N];
int degree[MAX_N];
int cnt = 0;
int head[MAX_N];
struct node
{
    int to, next, way;
} edge[MAX_N << 2];

struct node2
{
    int u, v, w;
} a[MAX_N << 1];

int top = 0;
int iq = 0;
int ans[MAX_N];
inline void init()
{
    memset(head, -1, sizeof(head));
    memset(vis, false, sizeof(vis));
    memset(degree, 0, sizeof(degree));
    memset(ans, 0 ,sizeof(ans));
    memset(a, 0, sizeof(a));
    iq = 0;
    top = 0;
    cnt = 0;
}

void add_edge(int u, int v, int w)
{
    edge[top].to = v;
    edge[top].way = w;
    edge[top].next = head[u];
    head[u] = top++;
}

void dfs(int now)
{
    for(int k = head[now] ; k != -1 ; k = edge[k].next)
    {
        int v = edge[k].to;
        if(!vis[edge[k].way])
        {
            vis[edge[k].way] = true;
            //vis[edge[k].way] = true;
            dfs(v);
            ans[iq++] = edge[k].way;
        }
    }
}

bool cmp(node2 a, node2 b)
{
    return a.w < b.w;
}

int main()
{
    int u, v, w;
    while(scanf("%d%d", &u, &v)&&(u + v))
    {
        init();
//        int cnt = 0;
//        int tot = 0;
        scanf("%d", &w);
        a[cnt].u = u;
        a[cnt].v = v;
        a[cnt].w = w;
        cnt++;
        int home = min(u, v);
        while(scanf("%d%d", &u, &v) && (u + v))
        {
            scanf("%d", &w);
            a[cnt].u = u;
            a[cnt].v = v;
            a[cnt].w = w;
            cnt++;
        }
        sort(a, a + cnt, cmp);
//        for(int i = 0 ; i < cnt ; i++)
//        {
//            cout<<a[i].u<<" "<<a[i].v<<" "<<a[i].w<<endl;
//        }
        for(int i = 0 ; i < cnt ; i++)
        {
            add_edge(a[i].u, a[i].v, a[i].w);
            add_edge(a[i].v, a[i].u, a[i].w);
            degree[a[i].u]++;
            degree[a[i].v]++;
        }
        int flag = 0;
        for(int i = 0 ; i < 50 ; i++)
        {
            if(degree[i] % 2)
            {
                flag = 1;
                break;
            }
        }
        if(flag)
        {
            printf("Round trip does not exist.\n");
            continue;
        }
        dfs(home);
        for(int i = 0 ; i < iq ; i++)
        {
            cout<<ans[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: