Judgment and find the path of Euler

Decision

First map must be Unicom, with disjoint-set can be sentenced

Undirected Tu Oula circuit: all points are an even number of degrees

Tuou La undirected paths: two points (points or 0) degrees is odd, the remaining points (or all points) in degrees is an even number

Directed Tuou La circuit: = penetration all points of the

Tuou La directed path: a point-degree out-degree = +1, a dot-degree out-degree = +1, the remaining points (or all points) out of the penetration =

Find -Hierholzer algorithm

//已知存在欧拉路径,找该路径
void dfs(int u){//s1~sn中存储的是欧拉路径上的点序列
    for(int v=1;v<=n;v++){
        if(mp[u][v]>0){
            mp[u][v]--;
            mp[v][u]--;
            dfs(v);
        }
    }
    s[temp--]=u;
}

Why is it right?

Because one side can find Eulerian paths into problem by Euler circuit between two points on the graph odd added. Can be found by enumerating the presence Euler FIG must be formed by nesting a number of rings (by some point into two approximately as cacti)

The main ring as a ring, a stroke to finish the main ring, as long as u first walk around the ring in the face of the sub-sub-rings have points, followed by walking along the main ring just fine

Hierholzer algorithm is a kind of thinking we are above the simple implementation:

We will start dfs the point of looking around the main part of the ring (you can actually there are many different possibilities, not necessarily the most obvious of the ring), the first time dfs unable to recursion, all the points to be traversed are in the main ring, it should be clear that the final traverse to the point where the final answer to the array, while back then, if you still can not be recursive, that answer into an array and then move forward from the back, if you can recursively instructions on this point there is a Deputy ring, deputy recursive loop along it, is the same final traverse to the point on the back, this way backwards before we simulated the algorithm.

example:

The Necklace

https://vjudge.net/contest/347059#problem/C

Each bead necklace has two sides, one color on each side, two adjacent faces of adjacent beads on the necklace must be the same color (necklace is a ring), a given number of beads and their colors, by asking whether the do all of the beads to be combined into a necklace?

Color Type = 50

Appearing one color regarded as a point on the graph, there is an edge, it is clear in such a Euler FIG if present, it may be composed of a necklace (traveled all the edges of a bead between two colors = exhausted all of the beads).

Disjoint-set + Hierholzer algorithm can be.

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
int a[maxn],b[maxn];
int mp[55][55];
int du[55];
int s[maxn],tot,temp;
void dfs(int u){
    for(int v=1;v<=50;v++){
        if(mp[u][v]>0){
            mp[u][v]--;
            mp[v][u]--;
            dfs(v);
        }
    }
    s[temp--]=u;
}
int fa[55],vis[55];
int find(int x){
    return x==fa[x]?x:fa[x]=find(fa[x]);
}
int main(){
    int T;
    cin>>T;
    for(int kase=1;kase<=T;kase++){
        int n;
        cin>>n;
        for(int i=1;i<=50;i++)fa[i]=i;
        memset(mp,0,sizeof(mp));
        memset(du,0,sizeof(du));
        memset(s,0,sizeof(s));
        memset(vis,0,sizeof(vis));
        tot=0;
        for(int i=1;i<=n;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            vis[u]=vis[v]=1;
            int fu=find(u),fv=find(v);
            fa[fu]=fv;
            mp[u][v]++;
            mp[v][u]++;
            du[u]++;
            du[v]++;
            tot++;
        }
        int cnt1=0;
        for(int i=1;i<=50;i++){
            if(vis[i]&&fa[i]==i)cnt1++;
        }
        if(cnt1>1){
            printf("Case #%d\nsome beads may be lost\n",kase);
            continue;
        }
        int flag=1;
        for(int i=1;i<=50;i++){
            if(du[i]&1){
                flag=0;
                break;
            }
        }
        if(!flag){
            printf("Case #%d\nsome beads may be lost\n",kase);
            if(kase<=T)printf("\n");
            continue;
        }
        temp=tot;
        for(int i=1;i<=50;i++){//找一个点
            if(vis[i]){
                dfs(i);
                break;
            }
        }
        printf("Case #%d\n",kase);
        for(int i=1;i<=tot;i++){
            printf("%d %d\n",s[i],s[i%tot+1]);
        }
        if(kase<=T)printf("\n");
    }
}

Guess you like

Origin www.cnblogs.com/ucprer/p/12005710.html