逆天思维题 CF741C

Arpa’s overnight party and Mehrdad’s silent entering

大意:
有2n个人围成一圈坐在桌子边上,每个人占据一个位子,对应这2n个人是n对情侣,要求情侣不能吃同一种食物,并且桌子上相邻的三个人的食物必须有两个人是不同的,只有两种食物(1或者是2),问一种可行分配方式。

思路:
因为只有两种颜色,所以是要我们构造一张二分图,其中情侣之间要连边,关键就是如何处理任意三个点之间的关系

题解的思路很巧妙。我们把2i-1与2i之间连边,这样肯定是能保证任意三个点之间不会全部相等

接下来看看如何证明这是一张二分图

一个结论:一张图是二分图的充要条件就是图中不存在奇环

我们会发现,每一个点都被两种边连接,一个来自它的伴侣,一个来自它的其中一个相邻点,所以最后如果有环的话,一定是两种边交替出现的,所以不可能有奇环(一个特殊情况是情侣相邻坐,但不难发现此时也不是奇环)。证毕。

code

#include 
#include 
#include 
using namespace std;
#define endl '\n'
#define ll long long
const ll N=2e5+10;
struct ty
{
    ll t,l,next;
}edge[N<<1];
ll cn=0;
ll n,a,b;
char c;
ll head[N];
void add_edge(ll a,ll b,ll c)
{
    edge[++cn].t=b;
    edge[cn].l=c;
    edge[cn].next=head[a];
    head[a]=cn;
}
ll e1[N],e2[N];
ll col[N];
void dfs(ll id,ll color)
{
    if(col[id]!=-1) return;
    col[id]=color;
    if(color==0) col[id]=2;
    for(int i=head[id];i!=-1;i=edge[i].next)
    {
        ll y=edge[i].t;
        dfs(y,color^1);
    }
}
void solve()
{
    memset(head,-1,sizeof(head));
    memset(col,-1,sizeof head);
    cin>>n;
    for(int i=1;i<=n;++i)
    {
        cin>>a>>b;
        e1[i]=a;e2[i]=b;
        add_edge(a,b,1);
        add_edge(b,a,1);
    }
    for(int i=1;i<=n;++i)
    {
        add_edge(2*i-1,2*i,1);
        add_edge(2*i,2*i-1,1);
    }
    for(int i=1;i<=n*2;++i)
    {
        if(col[i]==-1) dfs(i,0);
    }

    for(int i=1;i<=n;++i)
    {
        cout<

你可能感兴趣的:(思维题,搜索,图论,深度优先,算法,图论)