学习笔记——二分图与欧拉路

二分图:

概念:

节点由两个集合组成,且两个集合内部没有边的图

说白了,就是存在一种方案,将节点划分成拥有以上性质的图

判定:

使用BFS/DFS对图进行黑白染色,如果染色成功就是二分图

这个是一个概念,说实话没什么讲解必要、

典中典:

P1330

我不会打……

#include<bits/stdc++.h>
//#define int long long
#define ll long long
#define next nxt;
#define re register
#define il inline
using namespace std;
const int N=20010;
const int M=200010;
il int read()
{
    int f=0,s=0;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) f |= (ch=='-');
    for(; isdigit(ch);ch=getchar()) s = (s<<1) + (s<<3) + (ch^48);
    return f ? -s : s;
}
int top,g[N],ans;
int bla=0,whi=0;//定义黑白点
struct node{
    int a,b;
}ed[M];
int dfn[N],n,m,a,b;
bool vis[N],bol[N];
void add(int x,int y)
{
    ed[++top].a=y;
    ed[top].b=g[x];
    g[x]=top;
} 
bool dfs(int x,int y)
{
    bol[x]=y%2;
    if(bol[x])
    {
        bla++;
    }
    else
    {
        whi++;
    }
    vis[x]=1;
    for(int i=g[x];i;i=ed[i].b)
    {
        int p=ed[i].a;
        if(vis[p])
        {
            if((bol[p]^bol[x])==0)
            {
                return 0;
            }
                
        } 
        else 
        {
            if(!dfs(p,y+1))
            {
                return 0;
            }
        }
    } 
    return 1;
}
int main()
{
    cin>>n>>m;
    for (int i=1;i<=m;i++)
    {
        cin>>a>>b;
        add(a,b);
        add(b,a);
    }
    for (int i=1;i<=n;i++)
    {
        if(!vis[i])
        {
            whi=bla=0;
            if(!(dfs(i,0)))
            {
                cout<<"Impossible"<<endl;
                return 0;
            }
            ans+=min(whi,bla);
        }
        
    }
    cout<<ans<<endl;
    return 0;
}
posted @ 2022-07-18 20:14  美索maysoul  阅读(44)  评论(0)    收藏  举报