Wannafly挑战赛27 B-紫魔法师 (二分图)

链接:https://www.nowcoder.com/acm/contest/215/B
来源:牛客网
 

题目描述

“サーヴァント、キャスター、Medea。”--紫魔法师

给出一棵仙人掌(每条边最多被包含于一个环,无自环,无重边,保证连通),要求用最少的颜色对其顶点染色,满足每条边两个端点的颜色不同,输出最小颜色数即可

输入描述:

第一行包括两个整数n,m,表示顶点数和边数
n <= 100000, m <= 200000
接下来m行每行两个整数u,v,表示u,v之间有一条无向边,保证数据合法

输出描述:

一行一个整数表示最小颜色数

题解:

 不难发现,如果图中存在奇数环,答案必然为3,其他必为2,当然n=1时答案为1

AC代码:

1.并查集判断是否存在环

#include<iostream>
#include<string.h>
#include<vector>
#include<cstdio>
using namespace std;
const int maxn = 1e5+55;
vector<int> tree[maxn];
int pre[maxn];
bool vis[maxn];
bool flag;
int num;
void dfs(int s,int e,int m)
{
    if(s==e)
    {
        num = m;
        return ;
    }
    for(int i=0; i<tree[s].size(); i++)
    {
        if(!vis[tree[s][i]])
        {
            vis[tree[s][i]] = true;
            dfs(tree[s][i],e,m+1);
        }
    }
}
int Find(int x)        //并查集判断是否存在环
{
    int tep = x;
    while(tep!=pre[tep]) tep = pre[tep];
    while(pre[x]!=tep)
    {
        int k = pre[x];
        pre[x] = tep;
        x = k;
    }
    return tep;
}
void mix(int x,int y)
{
    int fx = Find(x);
    int fy = Find(y);
    if(fx!=fy)
        pre[fy] = fx;
    else                    //在x y之间存在环
    {
        memset(vis,false,sizeof(vis));
        vis[x] = true;
        dfs(x,y,1);
        if(num&1) flag = true;  //奇数环
    }
}
int main()
{
    int n,m,x,y;
    cin>>n>>m;
    for(int i=0;i<=n;i++)
        pre[i] = i;
    while(m--)
    {
        scanf("%d %d",&x,&y);
        if(flag) continue;
        tree[x].push_back(y);
        tree[y].push_back(x);
        mix(x,y);
    }
    if(n<=2) cout<<n;
    else if(flag) cout<<3;
    else cout<<2;
    return 0;
}

2.直接爆搜 


#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
const int maxn = 1e5+55;
vector<int> tree[maxn];
bool vis[maxn];
int col[maxn];
bool flag;
void dfs(int p)
{
    for(int i=0;i<tree[p].size();++i)
    {
        if(!vis[tree[p][i]])
        {
            col[tree[p][i]] = !col[p]; //相邻之间颜色不同
            vis[tree[p][i]] = true;
            dfs(tree[p][i]);
        }
        else
        {
            if(col[p]==col[tree[p][i]]) //存在环且颜色相同
            {
                flag = true;
                return ;
            }
        }
    }
}
int main()
{
    int n,m,x,y;
    cin>>n>>m;
    while(m--)
    {
        scanf("%d %d",&x,&y);
        tree[x].push_back(y);
        tree[y].push_back(x);
    }
    dfs(1);
    if(n<=2) cout<<n;
    else if(flag) cout<<3;
    else cout<<2;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41157137/article/details/83450509