sgu 101 Domino (欧拉路)

来源:互联网 发布:AV淘宝网 avtaobao.cc 编辑:程序博客网 时间:2024/05/01 05:01

题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=101

思路: 最裸的欧拉路的题目 把骨牌的每一面当成点 每一张骨牌的两面都建一条无向边 求出此图的一条欧拉路即可。

在此总结一下欧拉路的知识:

无向图的欧拉路的存在判定: 为连通图 度数为奇数的点的个数为0 or 2

欧拉路的输出:

1.度数为奇数的点的个数为0(此图存在欧拉回路)  任选一点 用dfs入栈记录 最后再倒着输出即可

2.度数为奇数的点的个数为2(非欧拉图)         选出度数为奇数的点 然后再进行dfs


代码中并查集的判联通部分可以用dfs代替


code:

#include <cstdio>#include <algorithm>#include <iostream>#include <cstring>using namespace std;const int maxn=10500;const int maxe=10500;struct edge{    int to,next,flag;} G[maxe];int head[maxn],si,du[maxn],way[maxe];int cnt,nn;bool vis[10];void add_edge(int s,int t){    G[si].flag=true;    G[si].to=t;    G[si].next=head[s];    head[s]=si++;    G[si].flag=true;    G[si].to=s;    G[si].next=head[t];    head[t]=si++;}int par[maxn],num[maxn];void init(int n_){    for(int i=0;i<=n_;i++){        par[i]=i;        num[i]=1;    }}int Find(int x){    if(x==par[x]) return x;    return par[x]=Find(par[x]);}void unite(int x,int y){    x=Find(x);    y=Find(y);    if(num[x]<num[y]){        par[x]=y;        num[y]+=num[x];    }    else{        par[y]=x;        num[x]+=num[y];    }}bool same(int x,int y){    return Find(x)==Find(y);}void dfs(int vv,int tt){    for(int i=head[vv];i!=-1;i=G[i].next){        if(!G[i].flag) continue;        G[i].flag=G[i^1].flag=false;        dfs(G[i].to,i);    }    if(tt!=-1) way[cnt++]=tt;}void output(int kk){    cnt=0;    if(kk==0){        for(int i=0;i<=6;i++){            if(!vis[i]) continue;            dfs(i,-1);            break;        }    }    else{        for(int i=0;i<=6;i++){            if(!vis[i]) continue;            if(du[i]%2!=0){                dfs(i,-1);                break;            }        }    }    for(int i=cnt-1;i>=0;i--){        if(way[i]%2) printf("%d -\n",way[i]/2+1);        else         printf("%d +\n",way[i]/2+1);    }}int main(){    int N,s,t,cnt1,cnt2,nn;    bool mark;    while(scanf("%d",&N)!=EOF){        init(N);        nn=0;        memset(vis,0,sizeof(vis));        memset(du,0,sizeof(du));        memset(head,-1,sizeof(head));        si=0;        for(int kk=0;kk<N;kk++){            scanf("%d%d",&s,&t);            add_edge(s,t);            du[s]++;            du[t]++;            if(!same(s,t))  unite(s,t);            vis[s]=vis[t]=true;        }        for(int i=0;i<=6;i++) if(vis[i]) nn++;        mark=0;        for(int i=0;i<=6;i++){            if(!vis[i]) continue;            if(num[Find(i)]!=nn){                printf("No solution\n");                mark=1;            }            break;        }        if(mark==1) continue;        cnt1=cnt2=0;        for(int i=0;i<=6;i++){            if(!vis[i]) continue;            if(du[i]%2==0) cnt1++;            else cnt2++;        }        if(cnt2==0) output(0);        else if(cnt2==2) output(1);        else printf("No solution\n");    }}


0 0
原创粉丝点击