Quantity statistics of connected subgraphs of ac graph and judgment of Euler pathway

The difference between Euler circuit and Euler circuit and its judgment

Euler road is often used when doing some graph classes, such as recent word connections and color sticks, etc., which are sorted out below:

Euler Path: A path that goes through each edge in the graph and only once, and goes through each vertex.

Euler circuit: A circuit that goes through each edge in the graph exactly once, and goes through every vertex.

 

Determining whether an undirected graph has an Euler path or loop:

Euler Path: The graph is connected; there are only 0 or 2 nodes with odd degree in the graph

Euler circuit: the graph is connected; all nodes in the graph have even degrees

 

Determining whether a directed graph has an Euler path or loop:

Euler path: graph is connected; in-degree = out-degree of all nodes except 2 endpoints; 1 endpoint in-degree is 1 greater than out-degree; an endpoint in-degree is 1 less than out-degree or all nodes have in-degree equal to out-degree

Euler circuit: the graph is connected; the in-degree of all nodes equals the out-degree

portal


one stroke problem

Time Limit: 3000  ms | Memory Limit: 65535  KB
Difficulty: 4
describe

Zyc likes to play some small games since he was a child, including drawing with one stroke. He wants to ask you to help him write a program to judge whether a picture can be drawn with one stroke.

It is stipulated that all edges can only be drawn once and cannot be drawn repeatedly.

 

enter
The first line has only one positive integer N (N<=10) representing the number of groups of test data.
The first line of each set of test data has two positive integers P, Q (P<=1000, Q<=2000), which respectively indicate how many vertices and how many lines there are in the painting. (The points are numbered from 1 to P)
The subsequent Q lines, each line has two positive integers A, B (0<A,B<P), indicating that there is a line between the two points numbered A and B.
output
如果存在符合条件的连线,则输出"Yes",
如果不存在符合条件的连线,输出"No"。
样例输入
2
4 3
1 2
1 3
1 4
4 5
1 2
2 3
1 3
1 4
3 4
样例输出
No
Yes


题目分析:首先这道题目拿来一看是判断是否有欧拉通路的题目,所以说根据条件要满足

1.必须是联通的图。

但是判断一个图是不是连同的,首先有两种方法

a.深搜或者广搜后接着扫面visit数组,如果有点没有被访问,那么说明有其他子图存在,但是这个算法是O(v^2)

b.运用并查集在输入每条边的同时该边的两个顶点所在的子图放在划分在一起并且将联通子集数目减一,如果最后的数目是1,也就是说只有一个联通图,那么改图是联通的.并查集加压缩路径复杂度小于O(nlogn),并且能够统计联通子集的数目。并且不用定义邻接矩阵或者是邻接表。

所以说b是最优的

2.奇数度顶点的个数是0或者是2

在读入每条边的时候由于是无向图所以将两个顶点的度数加一,全部边读入完成后统计奇数度点的个数即可



#include<iostream>//导入输入输出流头文件
#include<string.h>//用到函数memset
using namespace std;//导入标准明明空间
#define MAXE 2005//定义最大边的数目
#define MAXN 1005//定义最大顶点数目
int n,e;//顶点数目,边的数目
int pre[MAXN];//并查集的根节点数组
int cnt;//图中联通分量的个数
int du[MAXN];//定义图的各点度数的保存数组
int Find(int x)//压缩路径
{
    int p=x,temp;
    while(x!=pre[x])//返回该子连通图的父亲顶点
    x=pre[x];
    while(p!=x)//遍历从x到父节点的所有路径
    {
        temp=pre[p];
        pre[p]=x;//将路径的所有点的父节点直接赋值为x的父节点
        p=temp;
    }
    return x;//返回x的父节点
}
void init()//对于每个例子进行初始化
{
    for(int i=0;i<=n;i++)//初始化每个联通子图是自己一个顶点
        pre[i]=i;
        cnt=n;//即是有n个联通子图
        memset(du,0,sizeof(du));//初始化每个点度数为0
}
void join(int a,int b)
{
    if(Find(a)!=Find(b))
    {
        pre[pre[a]]=pre[b];//对于一条边上的两个点,如果不在一个联通子图中,那么就把他们划分到一个中
        cnt--;//联通子图减少一个
    }

}
bool is_ou_la()//判断是否符合欧拉通路
{
    int ji=0;
    for(int j=1;j<=n;j++)//统计度是奇数的个数
    {
        if(du[j]%2==1)
            ji++;
    }
    if(ji!=0&&ji!=2)//如果既不是0个也不是2个
        return false;//返回flase 不能一笔画
    else
    return true;//返回true、 表示存在欧拉通路

}
int main()
{
    ios::sync_with_stdio(false);//提高输入输出速度
    int ncase;
    cin>>ncase;//输入样例组数
    while(ncase--)
    {
        cin>>n>>e;
        init();//initialize first
        for(int i=0;i<e;i++)
        {
            int v,w;
            cin>>v>>w;
            du[v]++;//Add one to the two vertex degrees of the same edge
            you[w]++;
            join(v,w);//Join the two connected subgraphs where the two vertices of this edge are located
        }
        if(cnt==1&&is_ou_la())//If there is only one connected component left at the end, and there is an Euler path
        {
            cout<<"Yes"<<endl;//If the condition is met, output yes
        }
        else
            cout<<"No"<<endl;//Otherwise output no
    }
}


It can be said that this is very efficient.




Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326398212&siteId=291194637