codeforces #547D Mike and Fish 欧拉回路

题目大意:给定平面上的n个点,要求将每个点染成红色/蓝色,使得每行/每列的红色点数和蓝色点数之差≤1

将每一个横坐标/纵坐标看做一个点,每个点看做一条连接两个坐标的边

现在我们要将每条边染色使得每个点连接的所有边中两种颜色之差≤1

首先找到度数为奇数的点 这样的点一定有偶数个

将度数为奇数的点两两配对连边,这样所有点的度数就都是偶数了

然后对于每个连通块,任选一个初始度数为奇数的点(不存在则任选一个度数为偶数的点),求一条欧拉回路(如果起始点初始度数为奇数则要求先遍历新连接的边),然后将路径上的边红蓝染色即可

为什么这样做是对的呢?

考虑一条欧拉回路,染色后除了起始点外每个点连出的红色边和蓝色边数量都是相同的

而对于起始点,欧拉回路的第一条边和最后一条边染上的颜色可能是相同的

那么如果起始点的初始度数为奇数,由于我先遍历了新连接的边,因此即使第一条边和最后一条边颜色相同也没关系

如果起始点的初始度数为偶数,那么这个连通块是一个二分图,第一条边和最后一条边的颜色一定不同

因此这个做法是对的

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 400400
using namespace std;
struct abcd{
    int to,num,next;
    bool ban;
}table[800800];
int head[M],tot=1;
int n;
int degree[M],stack[M],top;
bool v[M];
char ans[M];
void Assert(bool flag)
{
    if(!flag)
    {
        puts("Fuck♂You!");
        exit(0);
    }
}
void Add(int x,int y,int z)
{
    table[++tot].to=y;
    table[tot].num=z;
    table[tot].next=head[x];
    head[x]=tot;
}
void DFS(int x)
{
    int i;
    v[x]=true;
    while(head[x])
    {
        i=head[x];
        head[x]=table[i].next;
        if(table[i].ban)
            continue;
        table[i^1].ban=true;
        DFS(table[i].to);
        stack[++top]=table[i].num;
    }
}
int main()
{
    int i,x,y;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&y);y+=200000;
        Add(x,y,i),Add(y,x,i);
        degree[x]++;degree[y]++;
    }
    static int a[M],tot;
    for(i=1;i<=400000;i++)
        if(degree[i]&1)
            a[++tot]=i;
    for(i=1;i<=tot;i+=2)
    {
        Add(a[i],a[i+1],0);
        Add(a[i+1],a[i],0);
    }
    for(i=1;i<=tot;i++)
        if(!v[a[i]])
        {
            DFS(a[i]);
            bool flag=false;
            while(top)
            {
                flag^=1;
                if(stack[top])
                {
                    //Assert(!ans[stack[top]]);
                    ans[stack[top]]=flag?‘r‘:‘b‘;
                }
                stack[top--]=0;
            }
        }
    for(i=1;i<=400000;i++)
        if(!v[i])
        {
            DFS(i);
            bool flag=false;
            while(top)
            {
                flag^=1;
                if(stack[top])
                {
                    //Assert(!ans[stack[top]]);
                    ans[stack[top]]=flag?‘r‘:‘b‘;
                }
                stack[top--]=0;
            }
        }
    //Assert(strlen(ans+1)==n);
    puts(ans+1);
    return 0;
}
时间: 2024-11-10 22:16:03

codeforces #547D Mike and Fish 欧拉回路的相关文章

codeforces 547D Mike and Fish 欧拉路径

题目链接:点击打开链接 题意: 给定二维平面上的n个点的坐标 问: 把每个点用红色或蓝色染色, 使得 水平共线(或者垂直共线)的 点 中红色与蓝色数量差不超过1. 思路: 我们建一个二部图,X集是x轴,Y集是y轴 那么点(1,5)就是 x集的 1向 y集的 5连一条边. 此时点就是用边来表示的,那我们的任务就是给边染色. 使得: 对于二部图中任意一个点, 点所连接的红边和蓝边数量差不超过1. 那么我们可以认为这个点的入边就是红色,出边就是蓝色.显然这就是一个欧拉路径. 所以爆搜欧拉路径即可. #

Codeforces 247D Mike and Fish

Mike and Fish 我们可以把这个模型转换一下就变成有两类点,一类是X轴, 一类是Y轴, 每个点相当于对应的点之间建一条边, 如果这条边变红两点同时+1, 变蓝两点同时-1. 我们能发现这个图其实是个二分图, 我们可以随便取一个点开始走路, 红蓝间隔开来,那么中间的点就权值不变, 对于最末尾的点虽然权值有改变,但是只会改变一次, 就这样一直走路直到所有的边都遍历完. #include<bits/stdc++.h> #define LL long long #define fi firs

cf547D. Mike and Fish(欧拉回路)

题意 题目链接 Sol 说实话这题我到现在都不知道咋A的. 考试的时候是对任意相邻点之间连边,然后一分没有 然后改成每两个之间连一条边就A了.. 按说是可以过掉任意坐标上的点都是偶数的数据啊.. #include<cstdio> #include<algorithm> #include<iostream> #include<vector> #include<cstring> #include<queue> #define Pair p

CF 547 D. Mike and Fish

D. Mike and Fish http://codeforces.com/contest/547/problem/D 题意: 给定平面上n个点,将这些点染成红或者蓝色,要求每行.每列红色点与蓝色点数量的差的绝对值<=1.输出方案(保证有解). 分析: 参考popoqqq的博客 将每行每列分别看做一个点,给定的每个点(x,y)拆成x->y的边,那么连边后的图是一个二分图. 这样我们可以将边染色,使得与每个点相连的两种颜色差<=1. 于是对于所有的欧拉回路,我们可以直接交替染色. 但是会

codeforces #305 D Mike and Fish

正解貌似是大暴搜? 首先我们考虑这是一个二分图,建立网络流模型后很容易得出一个算法 S->行 容量为Num[X]/2; 行->列 容量为1 且要求(x,y)这个点存在 列->T 容量为Num[Y]/2 这样子跑网络流之后我们就得到了一组解 但是我们考虑输出方案 对于每一行,如果Num[X]为偶数,那么显然输出方案是正确的 但是如果Num[x]为奇数,多出的那个显然既有可能是红的也可能是蓝的 但关键是我们不能确定他是红的或者蓝的,因为他的状态也会影响对应的列 同样,列的考虑也是同理 所以我

Codeforces 798D Mike and distribution - 贪心

Mike has always been thinking about the harshness of social inequality. He's so obsessed with it that sometimes it even affects him while solving problems. At the moment, Mike has two sequences of positive integers A = [a1, a2, ..., an] and B = [b1, 

Codeforces 798D Mike and distribution(贪心或随机化)

题目链接 Mike and distribution 题目意思很简单,给出$a_{i}$和$b_{i}$,我们需要在这$n$个数中挑选最多$n/2+1$个,使得挑选出来的 $p_{1}$,$p_{2}$,$p_{3}$,...,$p_{m}$满足 $a_{p1}+a_{p2}+a_{p3}+...+a_{p_{m}}>a_{1}+a_{2}+a_{3}+...+a_{n}$ $b_{p1}+b_{p2}+b_{p3}+...+b_{p_{m}}>b_{1}+b_{2}+b_{3}+...+b_

CodeForces 689C Mike and Chocolate Thieves (二分)

原题: Description Bad news came to Mike's village, some thieves stole a bunch of chocolates from the local factory! Horrible! Aside from loving sweet things, thieves from this area are known to be very greedy. So after a thief takes his number of choco

codeforces 798C Mike and gcd problem

C.Mike and gcd problem Mike has a sequence A?=?[a1,?a2,?...,?an] of length n. He considers the sequence B?=?[b1,?b2,?...,?bn] beautiful if the gcd of all its elements is bigger than 1, i.e. . Mike wants to change his sequence in order to make it beau