ICPC2019上海区域赛 K-Color-Graph题解


链接:https://ac.nowcoder.com/acm/contest/4370/K
来源:牛客网

题目描述(翻译版)

给出一个简单的图形 N 个顶点和 M 条边。简单图是无向图,它没有自环(两端的边连接到同一顶点),并且在任何两个不同的顶点之间不超过一个边。最初,每个边缘都是白色。每回合,您都可以选择白色边缘并将其涂成红色。不允许您生成仅由红色边组成的奇数长的环。可以涂成红色的最大边数是多少?

输入描述

输入的第一行给出了测试用例的数量,T(1 ≤ T ≤ 30)。随后是 T 测试用例。
对于每种情况,第一行仅包含两个整数 NM (2 ≤ N ≤ 16 ,1 ≤ M ≤ Ñ(Ñ - 1) / 2)*。
下一个的第 i 行 M 行描述第 i 个边:两个整数 ü,v 表示介于 üv 。保证没有自环和多个边。

输出描述

对于每个测试用例,输出一行包含 “ Case #x:y” 的行,其中 x 是测试用例编号(从1开始),y 是可以绘制为红色的最大边数。

输入

2
4 5
1 2
1 3
1 4
2 4
3 4
5 6
1 2
2 3
3 1
1 4
4 5
3 5

输出

Case #1: 4
Case #2: 5

算法分析

根据题目所说的:不允许您生成仅由红色边组成的奇数长的环。可以涂成红色的最大边数是多少?

也就是说要使得,最后红色的边形成的图中,不存在奇数长度的环。

***二分图的性质:二分图中的所有环都是偶数长度,不存在奇数长度的环。***

因此对于A集合中的情况进行枚举,那么B集合的情况也就唯一确定了,然后根据枚举的情况去寻找该情况下的最大边数,所有情况枚举完之后,取最大值即可。

解题代码

#include <bits/stdc++.h>
using namespace std;

const int maxn=105;
const int maxm=1e4+5;

struct edge{
    int u,v;
}E[maxm];	//记录边的内容

int tot=0;	//记录边数

void addedge(int u,int v){
    E[++tot].u=u;
    E[tot].v=v;
}

int color[maxn];	//用来标记点所在的集合,两个集合用 1|0 标示

int main(){
    int T;
    cin >> T;
    for(int kase = 1; kase <= T; kase++){
        int n,m;
        scanf("%d%d",&n,&m);
        fill(color, color+1+n, 0);
      
        tot = 0;
        for(int i = 1; i <= m; i++){
            int u,v;
            scanf("%d%d",&u,&v);
            addedge(u,v);
        }
      
      	//用于枚举二分图的所有情况,找出每种情况的最大值,就是最终结果
        int ans=0;
        for(int meijv = 0;meijv <= (1<<n) - 1; meijv++){
            int mj = meijv;
          	
          	//类似于二进制的操作,枚举四个位置的情况
         		//如 mj=0: 0000, mj=1: 1000, mj=2: 0100, mj=3: 1100 ......
            for(int i = 1; i <= n; i++){
                if(mj & 1){
                    color[i]=1;
                }
                else color[i]=0;
                mj >>= 1;
            }
          	//类似于二进制的操作,枚举四个位置的情况
          	
            int res=0;
            for(int i = 1; i <= tot; i++){
              	//当边的起点和终点不在一个集合时,就证明这个边是二分图的边
                if(color[E[i].u] != color[E[i].v]){
                    res++;
                }
            }
          	
            ans = max(ans, res);
        }
      	//用于枚举二分图的所有情况,找出每种情况的最大值,就是最终结果
      
        printf("Case #%d: %d\n",kase,ans);
    }
}

错题分析

二分图的概念

二分图
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

省下洗发水钱买书

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值