三色图

题目大意

给定一个二分图,请你给每条边一个颜色(0,1,2)
一个点的点权定义为其所有与之相连的边颜色和模3
任意一条边连接的两端点点权必须不同
请构造一种染色方案

结论

对每一个联通块进行分析。
首先说出我们的构造目标:左边点点权均为0,右边点点权均不为0,这样一定符合要求
具体构造方案是将右边的点分为两两一组,以其中一个为起点,另一个为终点,然后跑一条可行路径,因为是联通的,所以该路径一定存在。对于路径中经过的边,按1、2、1、2的去加,也就是路径中第一条经过的边颜色+1,第二条+2,第三条+1,第四条+2,以此类推。
我们发现,这样做,起点点权+1,终点点权+2,其余所有点点权不变!
但是,因为要两两一组,如果右边点的个数是奇数怎么办?
我们可以找到右边一个点权为1的点,以它为起点,以这个剩余的点为终点,再做一次。不过,我们应该想到,如果右边只有1个点,那一对都凑不成了!
但是如果左边有超过1个点,即使右边只有1个点,我们可以左右交换!
而显然, 无解的情况是左右都只有1个点。

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=3000+10,maxm=10000+10;
int h[maxn],s[maxn],x[maxn],y[maxn],go[maxm*2],next[maxm*2],co[maxm];
bool bz[maxn],pd[maxn];
int i,j,k,l,t,n,n1,n2,m,tot,xx,yy;
void add(int x,int y){
    go[++tot]=y;
    next[tot]=h[x];
    h[x]=tot;
}
void dfs(int i,int c){
    bz[i]=1;
    if (!c) x[++xx]=i;else y[++yy]=i;
    int t=h[i];
    while (t){
        if (!bz[go[t]]) dfs(go[t],1-c);
        t=next[t];
    }
}
bool dg(int x,int y,int c){
    pd[x]=1;
    if (x==y) return 1;
    int t=h[x];
    while (t){
        if (!pd[go[t]]&&dg(go[t],y,1-c)){
            (co[(t+1)/2]+=c+1)%=3;
            return 1;
        }
        t=next[t];
    }
}
void work(){
    int i;
    if (yy==1){
        swap(x[1],y[1]);
        fo(i,2,xx) y[i]=x[i];
        swap(xx,yy);
    }
    fo(i,1,yy/2){
        j=y[i*2-1];k=y[i*2];
        fo(l,1,xx) pd[x[l]]=0;
        fo(l,1,yy) pd[y[l]]=0;
        dg(j,k,0);
        s[j]=1;s[k]=2;
    }
    if (yy%2==1){
        j=y[1];k=y[yy];
        fo(l,1,xx) pd[x[l]]=0;
        fo(l,1,yy) pd[y[l]]=0;
        dg(j,k,0);
    }
}
int main(){
    scanf("%d%d%d",&n1,&n2,&m);
    fo(i,1,m){
        scanf("%d%d",&j,&k);
        add(j,k+n1);add(k+n1,j);
    }
    fo(i,1,n1)
        if (!bz[i]){
            xx=yy=0;
            dfs(i,0);
            work();
        }
    printf("Yes\n");
    fo(i,1,m) printf("%d ",co[i]);
}
在Python中,可以使用`matplotlib`和`numpy`库来绘制黑白灰三色。以下是一个简单的示例代码: ```python import numpy as np import matplotlib.pyplot as plt # 创建一个简单的二维数组作为像数据 image_data = np.random.rand(100, 100) # 显示像,使用灰度颜色映射 plt.imshow(image_data, cmap='gray') # 去除坐标轴 plt.axis('off') # 显示像 plt.show() ``` 在上述代码中,首先使用`numpy`的`random.rand`函数创建了一个100x100的随机二维数组,代表像数据。然后使用`matplotlib`的`imshow`函数显示像,并通过`cmap='gray'`参数指定使用灰度颜色映射,这样像就会以黑白灰三色显示。最后,使用`axis('off')`去除坐标轴,并使用`show`函数显示像。 如果要创建具有特定黑白灰分布的像,可以手动设置二维数组的值。例如: ```python import numpy as np import matplotlib.pyplot as plt # 创建一个全黑的像 black_image = np.zeros((100, 100)) # 创建一个全白的像 white_image = np.ones((100, 100)) # 创建一个灰色的像 gray_image = np.full((100, 100), 0.5) # 显示像 fig, axes = plt.subplots(1, 3, figsize=(15, 5)) axes[0].imshow(black_image, cmap='gray') axes[0].axis('off') axes[0].set_title('Black Image') axes[1].imshow(white_image, cmap='gray') axes[1].axis('off') axes[1].set_title('White Image') axes[2].imshow(gray_image, cmap='gray') axes[2].axis('off') axes[2].set_title('Gray Image') plt.show() ``` 在这个示例中,分别创建了全黑、全白和灰色的像,并使用`subplots`函数将它们显示在同一个中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值