USACO fence

  题目的意思就是给你一个图, 输出他的欧拉路(欧拉通路 或者 欧拉回路),无向图欧拉回路判断条件是:1:图连通 2:所有点的度数为偶数     无向图欧拉通路的条件是:1:图连通 2:有且只有两个点的度数为奇数, 不过寻找欧拉路的代码是一样的,学习了新的建图方法,代码如下:

/*
    ID: m1500293
    LANG: C++
    PROG: fence
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
struct edge
{
    int a, b, used;
    edge() {}
    edge(int a, int b, int used):a(a), b(b), used(used) {}
    int other(int x)
    {
        return x==a?b:a;
    }
}e[1100];
int F;    //边的数量
vector<int> G[510];
int node[510], nodenum, exist[510];
int degree[510];
vector<int> ans;

void dfs(int u)                  
{
    for(int i=0; i<G[u].size(); i++)
    {
        edge &tp = e[G[u][i]];
        if(!tp.used)
        {
            tp.used = 1;
            dfs(tp.other(u));
        }
    }
    ans.push_back(u);
}

struct cmp                  //高明
{
    int x;
    cmp() {}
    cmp(int x):x(x) {}
    bool operator()  (const int &a, const int &b) const
    {
        return e[a].other(x)<e[b].other(x);
    }
};

int main()
{
    //freopen("fence.in", "r", stdin);
    //freopen("fence.out", "w", stdout);
    memset(degree, 0, sizeof(degree));
    memset(exist, 0, sizeof(exist));
    nodenum = 0;
    scanf("%d", &F);
    for(int i=0; i<F; i++)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        if(!exist[u]) node[nodenum++] = u,  exist[u]=1;
        if(!exist[v]) node[nodenum++] = v,  exist[v]=1;
        degree[u]++; degree[v]++;
        e[i] = edge(u, v, 0);
        G[u].push_back(i);
        G[v].push_back(i);
    }
    sort(node, node+nodenum);
    for(int i=0; i<nodenum; i++)
        sort(G[node[i]].begin(), G[node[i]].end(), cmp(node[i]));
    int start = 0x3fffffff;
    for(int i=0; i<nodenum; i++)
        if(degree[node[i]]%2==1)
            start = min(start, node[i]);
    if(start == 0x3fffffff)
        start = node[0];
    dfs(start);
    for(int i=ans.size()-1; i>=0; i--)    //逆序输出
        printf("%d\n", ans[i]);
    return 0;
}

 

posted @ 2016-01-01 20:05  xing-xing  阅读(204)  评论(0编辑  收藏  举报