SGU 101. Domino 欧拉回路

来源:互联网 发布:阿里云搭建svn 编辑:程序博客网 时间:2024/05/01 03:51

题目大意

给定你n张骨牌,每张牌左右两端有一个数字,每张牌的左右两端数字可以颠倒,找出一种摆放骨牌的顺序,使得相邻骨牌的两端数字相同(最左边骨牌的最左端和最右边骨牌的最右端可以不管)。

解题思路

这是个很普通无向图欧拉回路,但是要注意判断这个图是否在一个连通分量里面!
输出No solution的条件有两个
1. 如果不满足欧拉回路的性质就输出
2. 如果不在一个连通分量
对应于第一个就是判断每个节点度,如果是0个或者两个就是欧拉回路
对于第二个来讲如果有节点没有访问过,就代表有不止一个连通分量
然后如果是有奇数度就选从奇数度中的任意一个出发,如果没有奇数度就随便选一个度不为0的 节点出发

AC代码

#include<cstdio>#include<cstring>#include<cmath>using namespace std;const int MAXN = 250;int head[MAXN],IN[MAXN];int start,path[MAXN],tot,edgeCnt;bool vis[MAXN];struct Edge{    int v,id,nxt;}E[MAXN<<1];void initEdge(){    edgeCnt = 0;    tot = 0;    memset(head,-1,sizeof head);    memset(IN,0,sizeof IN);    memset(vis,false,sizeof vis);}void addEdge(int u,int v,int id){    E[edgeCnt].v = v;    E[edgeCnt].id = id;    E[edgeCnt].nxt = head[u];    head[u] = edgeCnt++;}bool check(){    int count = 0;    for(int i = 0; i <= 6; i++)        if(IN[i]&1)        {            count++;            start = i;        }    if(count == 1||count > 2) return false;    if(count == 2) return true;    for(int i = 0; i <= 6; i++)        if(IN[i] > 0)        {            start = i;            break;        }    return true;}void Fleury(int u){    for(int i=head[u];~i;i=E[i].nxt)    {        int v = E[i].v;        int id = E[i].id;        if(!vis[(int)abs(id)])        {        //printf("[%d,%d]\n",v,id);            vis[(int)abs(id)] = true;            Fleury(v);            path[tot++] = id;        }    }}int main(){    int M;    int u,v;    while(~scanf("%d",&M))    {        initEdge();        for(int i=1;i<=M;i++)        {            scanf("%d%d",&u,&v);            addEdge(u,v,i);            addEdge(v,u,-i);            IN[u]++;            IN[v]++;        }        if(!check())        {            printf("No solution\n");            continue;        }        //printf("[%d]",start);        Fleury(start);        for(int i=1;i<=M;i++)            if(!vis[i]){                printf("No solution\n");                goto jumpEnd;            }        for(int i=tot-1;i>=0;i--)            if(path[i]>0) printf("%d +\n",path[i]);            else printf("%d -\n",-path[i]);jumpEnd:;    }    return 0;}
0 0
原创粉丝点击