• Relation(NOIP模拟赛)(二分图染色)


    原题:

    Description

    有n个人,编号为1àn,告诉你那些人之间是不友好的。现在,让你将这n个人分成两组,使得每一组之内的人是互相友好的,如果可以分成两组,则输出如何分组的,如果不可以分成两组,那么,输出“IMPOSSIBLE”。

    Input

    第一行两个整数n和m,1<=n<=50000,0<=m<=500000,分别表示人数以及不友好的人的对数。以下m行每行两个数a,b,表示a与b是不友好的。

    Output

    如果可以分成两个组,则输出一个方案,第一行为第一组的人的编号,第二行为第二组人的,按升序输出。其中,方案的字典序必须要最小,所谓的方案字典序最小,就是第一行和第二行连接,组成的序列的字典序最小,如果有多种分配方法,取第一个组别人数最多的方案。如果不能分成两组,输出“IMPOSSIBLE”。

    Sample Input(relation.in)

    5 4

    1 4

    1 5

    2 4

    2 5

    Sample Output(relation.out)

    1 2 3

    4 5

    样例解释:

    有两种方案,1 2 3 和 1 2

                4 5     3 4 5

    两种方案的字典序相同,取第一组人数最多的方案,所以输出方案一。

    题目满足:

    40%的数据n<=1000

    100%的数据n<=50000,m<=500000

    时限 1s

    这道题典型的二分图染色(因为分成2组)

    当然,根据题目,我们最后要SORT一下输出

    并且,方案字典序相同时,取第一组人数最多的方案

    所以染色的时候尽量多分配1,不行再回溯修改

    下面贴代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    struct edge{
        int to,next;
    }g[1000001];
    int color[50001];
    int head[50001],n,m;
    bool visit[50001];
    int ans1[50001],ans2[50001],num=0,num1=0,num2=0;
    void ins(int x,int y){g[++num].next=head[x];head[x]=num;g[num].to=y;}
    void insw(int x,int y){ins(x,y);ins(y,x);}
    bool dfs(int x){
        visit[x]=true;
        for(int i=head[x];i;i=g[i].next)
        {
            if(!visit[g[i].to])
            {
            color[g[i].to]=color[x]==1?0:1;
            visit[g[i].to]=true;
            if(!dfs(g[i].to))color[x]=color[x]==1?0:1;
            }
            else if(color[g[i].to]!=-1&&color[g[i].to]==color[x]){color[x]=color[x]==1?0:1;return false;}
        }
        return true;
    }
    int main(){
        freopen("relation.in","r",stdin);
        freopen("relation.out","w",stdout);
        memset(color,-1,sizeof(color));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            insw(x,y);
        }
        bool shuchu=false;
        for(int i=1;i<=n;i++)
        {
            if(color[i]==-1){color[i]=1;if(!dfs(i)){printf("IMPOSSIBLE
    ");shuchu=true;break;}}
        }
        if(!shuchu){
        for(int i=1;i<=n;i++)
        if(color[i]||color[i]==-1)ans1[++num1]=i; else ans2[++num2]=i;
        sort(ans1+1,ans1+num1+1);
        sort(ans2+1,ans2+num2+1);
        for(int i=1;i<num1;i++)
        printf("%d ",ans1[i]);
        printf("%d
    ",ans1[num1]);
        for(int i=1;i<num2;i++)
        printf("%d ",ans2[i]);
        printf("%d
    ",ans2[num2]);
        }
        fclose(stdin);
        fclose(stdout);
    }
  • 相关阅读:
    fabric 上传图片并添加到 canvas 中
    fabric 序列化增加额外属性
    fabric 按钮
    将 SVG 元素转成 dataUrl
    fabric button 通过子类实现
    fabric 鼠标点击绘制折线
    fabric 撤销保存重做 队列+指针
    fabric 鼠标动态绘制图形
    fabric 右键菜单
    supervisor 使用中遇到的问题
  • 原文地址:https://www.cnblogs.com/ghostfly233/p/6897562.html
Copyright © 2020-2023  润新知