zoukankan      html  css  js  c++  java
  • Bicoloring (并查集/二分图)

     

    题目链接

     

    题意:

      m个查询,每个查询输入a b,表示 顶点a b之间涂色。 规定只能涂颜色0 或者颜色 1,一个节点相连的边 必须涂成相同的颜色。 问 ,输入m组 a b之后,会不会犯规。

     

    思路:

      判断 a b 所在的环 边的数量 是奇还是偶。 奇数就不能,偶数就能。

      用并查集: 找到他们公共的祖先,判断(a到祖先的距离 + b到祖先的距离 +1 )的奇偶(最近的公共祖先 还是最远的公共祖先 都没关系,不影响奇偶) 。  如果a b没有公共祖先,就 f [fa] = fb合并起来就行。

      用搜索: 给每个顶点 标记值,如果相邻两个顶点的标记值相同,说明环是奇数,不满足。

     

    #include<iostream>
    #include<cstdio>
    #include <cctype>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<string>
    #include<cmath>
    #include<set>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    using namespace std;
    #define ll long long
    #define mem(a,x) memset(a,x,sizeof(a))
    #define se second
    #define fi first
    const ll mod=998244353;
    const int INF= 0x3f3f3f3f;
    const int N=2e5+5;
    
    int f[N];
    
    int getf(int x,int &s)
    {
        if(x!=f[x])
        {
            s++;
            f[x]=getf( f[x],s); //画图,压缩路径,加起来 
        }
        return f[x];
    }
    int main()
    {
        int n,k, a,b,v,fa,fb,q;
        int ans=0;
        while(cin>>n && n)
        {
            for(int i=0;i<=n;i++) f[i]=i;
            int flag=0;
            
            cin>>k;
            while(k--)
            {
                scanf("%d%d",&a,&b);
                if(flag==1) continue;
                int sa=0,sb=0;
                fa=getf(a,sa);
                fb=getf(b,sb);
                if(fa==fb){
                    if( (sa+sb+1)%2==1) //奇数环 
                    {
                        flag=1; 
                        continue;
                    }
                }
                else
                {
                    f[fa]=fb; 
                }
            }
            if(flag)
                cout<<"NOT BICOLORABLE."<<endl;
            else
                cout<<"BICOLORABLE."<<endl;
        } 
    }
    并查集
    #include<iostream>
    #include<cstdio>
    #include <cctype>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<string>
    #include<cmath>
    #include<set>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    using namespace std;
    #define ll long long
    #define mem(a,x) memset(a,x,sizeof(a))
    #define se second
    #define fi first
    const ll mod=998244353;
    const int INF= 0x3f3f3f3f;
    const int N=2e5+5;
    
    int n,m;
    int e[205][205] ;
    int book[N]; //用来标记每个顶点的颜色,即如果a b相连,顶点a 颜色为-1,
                 //那么b的颜色 一定要为1 (只有1,-1这两种颜色 ),否则就不满足 
    
    int bfs()
    {
        queue<int>q;
        q.push(0);  //应该题目 输入的全部数据一定有0顶点。 
        book[0]=-1;
        while(!q.empty())
        {
            int t=q.front();
            q.pop();
            for(int i=0;i<=n;i++)
            {
                if(e[t][i]) //顶点t到顶点i有边 
                {
                    if(book[i]) //i已经被遍历过
                    {
                        if(book[t]==book[i])  
                            return 1;
                    } 
                    else
                    {
                        book[i]= -book[t];
                        q.push(i);
                    }
                }
            } 
        }
        return 0;
    }
    int main()
    {
        while(cin>>n && n)
        {
            mem(e,0);
            mem(book,0);
            cin>>m;
            for(int i=1;i<=m;i++)
            {
                int xx, yy;
                scanf("%d%d",&xx,&yy);
                e[xx][yy]=e[yy][xx]=1 ;
            }
            if(bfs())
                cout<<"NOT BICOLORABLE."<<endl;
            else
                cout<<"BICOLORABLE."<<endl;
        } 
    }
    bfs搜索
  • 相关阅读:
    linux weblogic的sh文件
    linux 安装weblogic(转载)
    linux 安装jdk
    linux 用户和用户组
    测试开发工程师必备软硬能力&高级测试开发工程师需要具备什么能力?
    postman强大的团队协作功能
    requests(一): 发送一个json格式的post请求
    python操作Excel模块openpyxl
    appium环境安装app自动化
    夜神模拟器怎么连接adb
  • 原文地址:https://www.cnblogs.com/thunder-110/p/10322669.html
Copyright © 2011-2022 走看看