[Codeforces741C]Arpa’s overnight party and Mehrdad’s silent entering(二分图染色)

针对一个有趣的情侣就餐问题,本文介绍了一种解决方案。通过构建图模型并采用黑白染色法,确保情侣间的饮食选择不同且任意三人不会连续选择相同的食物。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://codeforces.com/contest/741/problem/C


题目描述
  要不我就用这次模拟考的题面吧哈哈哈写的好有趣:
  七夕节,有 对情侣围做在一个圆桌上吃饭。座位的编号为 1~2n(1<=n<=10^5) 。饭店老板作为大FFF团的一员,看着这一桌,身旁不知何时多了一根火把。 他想了想,觉得火把太暴力了,要让敌人从内部瓦解。于是,他决定让一对情侣两个人一个吃好吃的食物,一个吃难吃的食物,这样他们就会产生分歧,感情出现裂痕…… 同时,任意连续3人也不能都吃到难吃的食物或都吃到好吃的食物。注意:1 和 2n是相邻的。老板现在还沉浸在想出这个妙招的喜悦中,分配食物的方案就交给你了。

输入格式
第一行一个数 ,表示情侣的对数。
接下来 行,每行两个数,分别表示第 对情侣两个人就座的位置。
输入保证每个位置恰好有一个人坐。
输出格式
如果有解,则输出 行,每行两个数,表示第 对情侣两个人的食物。 代表难吃的, 代表好吃的。 无解输出 -1

样例输入
3
1 4
2 5
3 6
样例输出
1 2
2 1
1 2


解法:
  这道题有两个突破点:
  1、情侣要不同
  2、相邻的三个人不能相同
  那么我们考虑把每个人看成一个点,构一个图,用黑白染色的方法来让一条边的两端的点不一样。那么怎么构图呢?
  显而易见,要满足条件1,对情侣之间连一条无向边即可。
  要满足条件2,我们可以对2i和2i-1连一条无向边(也就是1–2,3–4),为什么,举个例子,假如我们现在是1–2,3–4,最坏的情况是2,3相同,但是由于1和2相连,3和4相连所以1和2不同,3和4不同,所以不会有连续三个相同的情况。


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
    int x,y,next;
}t[400010]; int len,last[200010];
void ins(int x,int y)
{
    t[++len].x=x;t[len].y=y;
    t[len].next=last[x];last[x]=len;    
}
int a[200010],b[200010],ans[200010];
void dfs(int x,int w)
{
    ans[x]=w;
    for(int k=last[x];k;k=t[k].next)
    {
        int y=t[k].y;
        if(!ans[y]) dfs(y,3-w);
    }
}
int main()
{
    int n; scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&a[i],&b[i]);
        ins(a[i],b[i]);
        ins(b[i],a[i]);
    }
    for(int i=1;i<=n;i++)
    {
        ins(i*2-1,i*2);
        ins(i*2,i*2-1); 
    }
    for(int i=1;i<=2*n;i++)
        if(!ans[i])
            dfs(i,1);
    for(int i=1;i<=n;i++)
        printf("%d %d\n",ans[a[i]],ans[b[i]]);
    return 0;
}
### Codeforces 平台上的二分图染色算法题目 #### CF1949I. Disks 的解题思路 对于给定的一组圆盘,判断是否存在一种方式使得这些圆盘能够通过改变大小来满足特定条件。如果存在某个圆既变小又变大,或者变小的圆的数量不等于变大的圆的数量,则该连通块无法实现目标状态[^5]。 为了验证这一点,可以采用二分图染色的方法: - 将每个圆视为图中的节点; - 如果两个圆之间有交集,则在这两个节点间建立一条边; - 使用两种不同的颜色尝试对整个图形进行着色,在此过程中遇到冲突则说明不存在合法方案; 这种方法不仅适用于本题描述的情况,也广泛应用于其他涉及二分性质的问题求解中。 #### 构造性算法实例 在解决一些具有构造特性的编程挑战时,比如构建IP地址这样的任务[T1 IP地址(ip)][^2],虽然这并不是典型的二分图问题,但是当涉及到如何有效地分配资源(如同一网络内的设备编号),也可以借鉴类似的思维模式——即合理规划不同部分之间的关系以达到最优配置效果。 ```cpp // C++ code snippet demonstrating bipartite graph coloring approach #include <bits/stdc++.h> using namespace std; const int MAXN = 1e5 + 7; int color[MAXN]; vector<int> adj[MAXN]; bool dfs(int u, int c) { color[u] = c; for (auto v : adj[u]) { if (!color[v]) { if (!dfs(v, 3 - c)) return false; // alternate colors between 1 and 2 } else if (color[v] == c) return false; // found an odd cycle or conflict } return true; } void solve() { memset(color, 0, sizeof(color)); bool isBipartite = true; for (int i = 1; i <= n && isBipartite; ++i) { if (!color[i]) isBipartite &= dfs(i, 1); } cout << (isBipartite ? "YES\n" : "NO\n"); } ``` 上述代码展示了利用深度优先搜索(DFS)来进行二分图检测的过程。这里假设输入已经准备好了一个无向图的数据结构`adj[]`表示邻接表形式存储的图以及顶点数量n。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值