Difficulty of graph theory

The meaning of problems

Is given by \ (n-\) points \ (m \) no edges connected graph composition, to ensure that no heavy edges and loopback.
You need to find out all the edges, these edges meet exactly exist in a simple ring. A ring is known as a simple ring, if and only if
all the points that it contains only the elapsed time in this loop.
These edges may have noticed a lot of pieces, you just need the output of XOR and their number can be.

Thinking

The spanning tree can start dfs FIG
understood any of a simple ring must contain a non-tree edge
playing examples can be found, if an edge is present in a simple loop, if and only if it satisfies one of the following two conditions :

  • This non-edge side of the tree, and it does not cover the side of the tree, and any other non-tree edge side of the tree covered with a common edge
  • This side is the side of the tree, and its non-covered side of the tree satisfies the above conditions

So we can add to each non-chain side of the tree-covered side of the tree, the addition was complete enumeration of each non-tree edge statistical answer

Implementation

Can be calculated using a tree difference ideological side of each side of the tree is covered with how many non-tree, we call it \ (val [i] \)
If this non-covered tree tree side edge \ (val [i] \) are \ (1 \) , you can accumulate
it and how to determine the cumulative? Can be done with the prefix (see specific code)
(there is a mysterious skin properties: point on the ring to form a chain spanning tree, so do not seek \ (LCA \) )

Precautions

  • Build two-way side
  • Note the order, not with a simple ring plus twice

I do not know why, always pay up \ (RE \)
finally can not stand hanging open

int size=40<<20;//40M
__asm__ ("movq %0,%%rsp\n"::"r"((char*)malloc(size)+size));//网站开栈

Also found an interesting thing: general questions about the ring should be built out of the tree and then consider the relationship side of the tree and non-tree edge

code

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+50000;
int n,m,tot,ans;
int fi[N],ne[N<<1],to[N<<1],w[N<<1];
int val[N],dep[N],s[N],asd[N];
bool pd[N];
inline int read()
{
    int s=0,w=1; char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-')w=-1;
    for(;isdigit(ch);ch=getchar())s=(s<<1)+(s<<3)+(ch^48);
    return s*w;
}
inline void add(int x,int y,int s)
{
    ne[++tot]=fi[x],fi[x]=tot,to[tot]=y,w[tot]=s;
}
void dfs1(int x,int pr)
{
    dep[x]=dep[pr]+1;
    pd[x]=true;
    for(int i=fi[x];i;i=ne[i])
    {
        int v=to[i];
        if(v==pr) continue;
        if(pd[v])
        {
            if(dep[v]>dep[x]) continue;//顺序问题
            ++val[x],--val[v];
            continue;
        }
        dfs1(v,x);
    }
}
void dfs2(int x,int pr)
{
    pd[x]=true;
    for(int i=fi[x];i;i=ne[i])
    {
        int v=to[i];
        if(v==pr||pd[v]) continue;
        asd[v]=asd[x]^w[i];
        dfs2(v,x);
        val[x]+=val[v];
    }
}
void dfs3(int x,int pr)
{
    pd[x]=true;s[x]=s[pr]+val[x];
    for(int i=fi[x];i;i=ne[i])
    {
        int v=to[i];
        if(v==pr) continue;
        if(pd[v])
        {
            if(dep[v]>dep[x]) continue;
            if((dep[x]-dep[v])==(s[x]-s[v]))
                ans^=asd[x]^asd[v]^w[i];
            continue;
        }
        dfs3(v,x);
    }
}
int main()
{
    int size=40<<20;//40M
    __asm__ ("movq %0,%%rsp\n"::"r"((char*)malloc(size)+size));
    n=read(),m=read();
    for(int i=1;i<=m;++i)
    {
        int a=read(),b=read();
        add(a,b,i);add(b,a,i);
    }
    dfs1(1,0);
    for(int i=1;i<=n;++i)pd[i]=false;
    dfs2(1,0);
    for(int i=1;i<=n;++i)pd[i]=false;
    dfs3(1,0);
    cout<<ans;
    exit(0);
}

Guess you like

Origin www.cnblogs.com/zmyzmy/p/12112294.html