ACM/ICPC 之 DFS求解欧拉通路路径(POJ2337)

  判断是欧拉通路后,DFS简单剪枝求解字典序最小的欧拉通路路径

//Time:16Ms     Memory:228K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

#define MAX 1005
#define MAXS 24 //姓名
#define MAXN 26 //字母

struct Edge{
    char name[MAXS];
    int a,b;
    friend bool operator < (Edge &e1, Edge &e2)
    { return strcmp(e1.name, e2.name) < 0; }
}e[MAX];

int n;
int in[MAXN], out[MAXN];    //入度与出度
int order[MAX];     //顺序路径
bool v[MAX];

bool dfs(int x, int rk)
{
    if(rk == n) return true;
    for(int i = 0; i < n; i++)
    {
        if(!v[i] && x == e[i].a){
            v[i] = true;
            order[rk] = i;
            if(dfs(e[i].b, rk+1)) return true;
            v[i] = false;
        }
    }
    return false;
}

int main()
{
    //freopen("in.txt","r",stdin);

    int T;
    scanf("%d",&T);
    while(T--){
        memset(e,0,sizeof(e));
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        memset(order,-1,sizeof(order));
        memset(v,false,sizeof(v));
        scanf("%d",&n);
        //构图
        int st = 26;    //st:起点
        for(int i = 0; i < n; i++)
        {
            scanf("%s",e[i].name);
            e[i].a = e[i].name[0] - ‘a‘;
            e[i].b = e[i].name[strlen(e[i].name) - 1] - ‘a‘;
            out[e[i].a]++;
            in[e[i].b]++;
            if(e[i].a < st) st = e[i].a;
        }
        sort(e,e+n);
        //欧拉路判定
        int odd = 0;    //奇度结点个数
        bool flag = true;
        for(int i = 0 ; i < MAXN; i++)
        {
            if(in[i] != out[i])
            {
                odd++;
                if(out[i] - in[i] == 1)
                    st = i;
                else if(out[i] - in[i] != -1)
                {
                    flag = false;
                    break;
                }
            }
        }
        if(flag && (odd ==2 || odd == 0) && dfs(st,0))  //满足欧拉通路(排除非连通)+完整路径(判断非连通)
        {
            for(int i = 0; i < n - 1; i++)
                printf("%s.", e[order[i]].name);
            printf("%s\n", e[order[n-1]].name);
        }
        else printf("***\n");

    }

    return 0;
}
时间: 2024-10-03 23:29:20

ACM/ICPC 之 DFS求解欧拉通路路径(POJ2337)的相关文章

ACM/ICPC 之 DFS求解欧拉回路+打表(POJ1392)

本题可以通过全部n位二进制数作点,而后可按照某点A的末位数与某点B的首位数相等来建立A->B有向边,以此构图,改有向图则是一个有向欧拉回路,以下我利用DFS暴力求解该欧拉回路得到的字典序最小的路径. //求咬尾数,一个2^n位环形二进制数,该二进制的每n位连续二进制数都不同 //DFS求解欧拉回路 //Time:32ms Memory:1668K #include<iostream> #include<cstring> #include<cstdio> using

图论——欧拉通路、欧拉回路(有向图无向图混合图)

之前稍微了解有向图.无向图.混合图的欧拉通路.欧拉回路,这里做下笔记,以便日后翻阅. 无向图: 存在欧拉回路的条件:原图连通,每个结点均为偶度结点. 存在欧拉通路的条件:存在欧拉回路,或原图连通,有两个结点为奇度结点,其他结点均为偶度结点. 有向图: 存在欧拉回路的条件:基图连通,每个结点的入度等于出度. 存在欧拉通路的条件:存在欧拉回路,或基图连通,有一个结点入度等于出度+1,有一个结点出度等于入度+1,其他结点的入度等于出度. 混合图: 存在欧拉回路的条件: 1.将无向边随便定向,每个结点的

POJ 1386 Play on Words(有向欧拉通路 连通图)

题意  见下方中文翻译 每一个单词能够看成首尾两个字母相连的一条边  然后就是输入m条边  推断是否能构成有向欧拉通路了 有向图存在欧拉通路的充要条件: 1. 有向图的基图连通: 2. 全部点的出度和入度相等  或者  仅仅有两个入度和出度不相等的点  且这两点入度与出度的差一个为-1(起点)一个为1(终点). 推断是否连通就是应用并查集了 #include<cstdio> #include<cstring> using namespace std; const int N = 3

欧拉通路是否存在

//题目:一个字符串数组例如 abcd dcsg gec就输出true否则输出false; 这个问题就转化成一个图中是否存在欧拉通路问题.这里主要考虑的情况就是存在环的情况,所以当存在环的时候用深度遍历,只要看从一个点能不能经过所有点即可,选择dfs的起点的话分两种情况,如果有度为1的点就选择其中度为1的点,如果度都大于1的话就遍历所有点.代码如下: #include <iostream> #include <cstring> #include <vector> #de

有关欧拉通路/回路的一些资料整理

这两天看了下欧拉回路,整理下资料,以备以后回顾. 1.欧拉回路,欧拉通路,欧拉图 无向图: 1)设G为连通无向图,则称经过G的每条边一次仅且一次的路径为欧拉通路. 2)如果欧拉通路是回路(起点和终点是同一个顶点),则称此回路为欧拉回路. 3)具有欧拉回路的无向图G称为欧拉图. 有向图: 1)设D是连通有向图,则称经过G的每条边一次仅且一次的有向路径为有向欧拉通路. 2)如果有向欧拉通路是回路,则称此回路为有向欧拉回路. 3)具有有向欧拉回路的有向图G称为有向欧拉图. 2.定理及推论 定理1:无向

HDU 5883 F - The Best Path 欧拉通路 &amp; 欧拉回路

给定一个图,要求选一个点作为起点,然后经过每条边一次,然后把访问过的点异或起来(访问一次就异或一次),然后求最大值. 首先为什么会有最大值这样的分类?就是因为你开始点选择不同,欧拉回路的结果不同,因为是回路,所以你的开始点就会被访问多一次,所以如果是欧拉回路的话,还需要O(n)扫一次,枚举每个点作为起点. 欧拉通路的话,结果是固定的,因为只能从奇数度小的那个点作为起点,奇数度大的那个点作为终点. 关于点的访问次数:anstime  = Degree[i] / 2; //如果是奇数的,还要加上一.

关于欧拉通路、欧拉回路的一些定理,推论

关于欧拉通路.欧拉回路的一些定义: 无向图:G是一个连通的无向图(1)经过G的每条边一次并且仅一次的路径为欧拉通路(起点和终点不一定要一样).(2)如果欧拉通路是回路(起点和终点是同一个),则为欧拉回路.(3)具有欧拉回路的无向图G称为欧拉图. 有向图:D是一个有向图,D的基图(把D的有向边改为无向边)是连通的(1)经过D的每条边一次并且仅一次的路径称为有向欧拉通路(起点和终点不一定一样).(2)如果有向欧拉通路是回路(起点和终点一样),那么称为有向欧拉通路.(3)具有有向欧拉通路的有向图D称为

poj 2513 Colored Sticks(欧拉通路+并查集+字典树)

题目链接:poj 2513 Colored Sticks 题目大意:有N个木棍,每根木棍两端被涂上颜色,现在给定每个木棍两端的颜色,不同木棍之间拼接需要颜色相同的 端才可以,问最后能否将N个木棍拼接在一起. 解题思路:欧拉通路+并查集+字典树.欧拉通路,每个节点的统计度,度为奇数的点不能超过2个.并查集,判断节点 是否完全联通.字典树,映射颜色. #include <cstdio> #include <cstring> #include <string> #includ

POJ2513Colored Sticks(欧拉通路)(字典树)(并查集)

Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Total Submissions: 35612   Accepted: 9324 Description You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a st