二分图判定

题目大意:给定具有n个顶点m条边的图。要给每个顶点上色,并且要求相邻的顶点颜色不同,问的是能否用两种颜色进行染色,题目保证没有重边和自环

限制条件:1<=m,n<=1000

输入

n=3,m=3

0 1

0 2

1 2

输出

NO

输入

n=4 m=4

0 1 

0 3

1 3

2 3

输出

YES

个人思路:这是学过的第一道图论题,特地去学了vector的用法,思路全部在代码中

看代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<set>
#include<queue>
#include<map>
typedef long long ll;
using namespace std;
const ll mod=1e9+7;
const int maxn=1e3+10;
const int maxk=100+10;
const int maxx=1e4+10;
const ll maxa=2520;
#define INF 0x3f3f3f3f3f3f
vector<int> G[maxn];//
int color[maxn];//代表每个点的颜色,初始化为0,-1和1代表两种不同的颜色
int n,m;
bool dfs(int v,int c)
{
    color[v]=c;//把顶点v上色为c
    for(int i=0;i<G[v].size();i++)
    {
        //如果相邻的已经上色为同一种颜色,代表失败
        if(color[G[v][i]]==c)
            return false;
        //如果相邻的点没有上色,则上色的同时判断上色是否会导致矛盾
        if(color[G[v][i]]==0&&!dfs(G[v][i],-c))
            return false;
        //剩下的一种情况就是已经上色了,并且跟自己颜色相反,无需操作
    }
    return true;//所有与之相邻的顶点都已上色
}
void solve()
{
    for(int i=0;i<n;i++)
    {//为何要有一个循环,是因为防止该图是非连通图
        if(color[i]==0)//代表没有被上色
        {
            //上色为1
            if(!dfs(i,1))
            {
                cout<<"NO"<<endl;
                return ;
            }
        }
    }
    cout<<"YES"<<endl;
}
int main()
{
    ios::sync_with_stdio(false);
    memset(color,0,sizeof(color));
    int u,v;
    cin>>n>>m;//n代表n个顶点,m代表m条边
    for(int i=0;i<m;i++)
    {
        cin>>u>>v;
        G[u].push_back(v);//表示u,v相连
    }
    solve();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/caijiaming/p/9378400.html