问题描述

\(N\) 个齿轮每个齿轮有颜色(RGB),有些齿轮之间会咬合,你需要删除尽量少的齿轮并给每种颜色安排方向使得咬合齿轮不同向。问最多保留多少个齿轮。保证不存在两个相同颜色的齿轮咬合。

submit


交互输入输出大毒瘤!

题解

发现对于 RGB 三种颜色的齿轮,相同颜色不会自己和自己咬合。

所以可以枚举哪一种颜色的必须保留,剩下来两种咬合就连边,显然是个二分图。


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std; //#define local const int INF=0x3f3f3f3f; int n,S,T;
int ok[60][60]; int Head[200],to[10007],Next[10007],w[10007],tot=1; void addedge(int x,int y,int z){
to[++tot]=y,Next[tot]=Head[x],Head[x]=tot,w[tot]=z;
} void add(int x,int y,int z){
addedge(x,y,z);addedge(y,x,0);
} int d[200]; bool bfs(void){
memset(d,0,sizeof(d));
queue<int>q;q.push(S);d[S]=1;
while(q.size()){
int x=q.front();q.pop();
for(int i=Head[x];i;i=Next[i]){
int y=to[i];
if(d[y]||!w[i]) continue;
d[y]=d[x]+1;q.push(y);
if(y==T) return true;
}
}
return false;
} int dfs(int x,int flow){
if(x==T) return flow;
int rest=flow;
for(int i=Head[x];i&&rest;i=Next[i]){
int y=to[i];
if(d[y]!=d[x]+1||!w[i]) continue;
int k=dfs(y,min(rest,w[i]));
if(!k) d[y]=0;
else w[i]-=k,w[i^1]+=k,rest-=k;
}
return flow-rest;
} int Dinic(void){
int t,res(0);
while(bfs()){
while(t=dfs(S,INF)) res+=t;
}
return res;
} string col,s[50]; void Init(void){
cin>>n;cin>>col;
for(int i=0;i<n;i++) cin>>s[i];
} vector <int> v[4]; void clear(void){
tot=1;S=T=0;
memset(Head,0,sizeof(Head));
memset(Next,0,sizeof(Next));
} void debug(void){
for(int i=2;i<=tot;i+=2){
printf("-- From %d to %d w = %d \n",to[i^1],to[i],w[i]);
}
printf("## S = %d , T = %d\n",S,T);
} void Graph_build(int save){
clear();
S=2*n+1,T=S+1;
int st,nd;
if(save==1) st=2,nd=3;
else if(save==2) st=1,nd=3;
else st=1,nd=2;
for(int i=0;i<(int)v[st].size();i++){
for(int j=0;j<(int)v[nd].size();j++){
int x=v[st][i],y=v[nd][j];
if(s[x-1][y-1]=='Y') add(x,y+n,1);
}
}
for(int i=1;i<=n;i++){
// add(i,i+n,1);
add(S,i,1);add(i+n,T,1);
}
// debug();
} void Preprocess(void){
for(int i=0;i<n;i++){
int pos;
if(col[i]=='R') pos=1;
else if(col[i]=='B') pos=2;
else pos=3;
v[pos].push_back(i+1);
}
} int Work(void){
Preprocess();
int maxflow;
Graph_build(1);
maxflow=Dinic();
// printf("** %d\n",maxflow);
Graph_build(2);
int tmp=Dinic();
maxflow=min(maxflow,tmp);
// printf("** %d\n",tmp);
Graph_build(3);
tmp=Dinic();
maxflow=min(maxflow,tmp);
// printf("** %d\n",tmp);
return maxflow;
} void Main(void){
#ifdef local
freopen("hzlbn.in","r",stdin);
// freopen("debug.log","w",stdout);
#endif
Init();
Work();
} class GearsDiv1{
public:
int getmin(string ss,vector<string>md){
col=ss;n=ss.size();
for(int i=0;i<n;i++) s[i]=md[i];
Init();
return Work();
}
};

TopCoder12729 「SRM589Medium」GearsDiv1 二分图最小点覆盖的更多相关文章

  1. POJ2226 Muddy Fields(二分图最小点覆盖集)

    题目给张R×C的地图,地图上*表示泥地..表示草地,问最少要几块宽1长任意木板才能盖住所有泥地,木板可以重合但不能盖住草地. 把所有行和列连续的泥地(可以放一块木板铺满的)看作点且行和列连续泥地分别作 ...

  2. POJ1325 Machine Schedule(二分图最小点覆盖集)

    最小点覆盖集就是在一个有向图中选出最少的点集,使其覆盖所有的边. 二分图最小点覆盖集=二分图最大匹配(二分图最大边独立集) 这题A机器的n种模式作为X部的点,B机器的m种模式作为Y部的点: 每个任务就 ...

  3. hihoCoder #1127:二分图最小点覆盖和最大独立集

    题目大意:求二分图最小点覆盖和最大独立集. 题目分析:如果选中一个点,那么与这个点相连的所有边都被覆盖,使所有边都被覆盖的最小点集称为最小点覆盖,它等于最大匹配:任意两个点之间都没有边相连的最大点集称 ...

  4. [POJ] 2226 Muddy Fields(二分图最小点覆盖)

    题目地址:http://poj.org/problem?id=2226 二分图的题目关键在于建图.因为“*”的地方只有两种木板覆盖方式:水平或竖直,所以运用这种方式进行二分.首先按行排列,算出每个&q ...

  5. 二分图 最小点覆盖 poj 3041

    题目链接:Asteroids - POJ 3041 - Virtual Judge  https://vjudge.net/problem/POJ-3041 第一行输入一个n和一个m表示在n*n的网格 ...

  6. LoibreOJ 2042. 「CQOI2016」不同的最小割 最小割树 Gomory-Hu tree

    2042. 「CQOI2016」不同的最小割 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  7. HihoCoder1127 二分图三·二分图最小点覆盖和最大独立集

    二分图三·二分图最小点覆盖和最大独立集 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上次安排完相亲之后又过了挺长时间,大家好像都差不多见过面了.不过相亲这个事不是说 ...

  8. 四川第七届 D Vertex Cover(二分图最小点覆盖,二分匹配模板)

    Vertex Cover frog has a graph with nn vertices v(1),v(2),…,v(n)v(1),v(2),…,v(n) and mm edges (v(a1), ...

  9. LibreOJ2042 - 「CQOI2016」不同的最小割

    Portal Description 给出一个给出一个\(n(n\leq850)\)个点\(m(m\leq8500)\)条边的无向图.定义\(cut(s,t)\)等于\(s,t\)的最小割的容量,求在 ...

随机推荐

  1. JavaScript新手经常遇到的问题(一)

    1.:before和:after,position: absolute;才可以调节高宽 2.判断背景颜色 2.1.$(this).css("background-color")== ...

  2. Android多线程之(一)View.post()源码分析——在子线程中更新UI

    提起View.post(),相信不少童鞋一点都不陌生,它用得最多的有两个功能,使用简便而且实用: 1)在子线程中更新UI.从子线程中切换到主线程更新UI,不需要额外new一个Handler实例来实现. ...

  3. 你真的了解JSON吗?

    一.JSON——JavaScript Object Notation JSON 是一种语法用来序列化对象.数组.数值.字符串.布尔值和null .它基于 JavaScript 语法,但与之不同:一些J ...

  4. 线性规划VB求解

    线性规划VB求解 Rem 定义动态数组 Dim a() As Single, c() As Single, b() As Single, cb() As Single Dim aa() As Sing ...

  5. ARTS-S docker安装miniconda

    FROM centos:centos7.3.1611 MAINTAINER zhouyang3 <aaa@qq.com> WORKDIR /usr/local ADD ./ /usr/lo ...

  6. 大数据学习笔记——Sqoop完整部署流程

    Sqoop详细部署教程 Sqoop是一个将hadoop与关系型数据库之间进行数据传输,批量数据导入导出的工具,注意,导入是指将数据从RDBMS导入到hadoop而导出则是指将数据从hadoop导出到R ...

  7. Obeject.hasOwnProperty

    对象{ }要用for-in遍历对象内的属性,通过hasOwnProperty判断属性是否是对象本身的,而不是原型上的 数组[ ]可以通过forEach来遍历

  8. ORA-19625: error identifying file

    问题描述:rman进行备份的时候,出现报错ORA-19625,无效的文件 1.进行数据库备份,然后就出现了报错,没有这个24号的归档日志 RMAN> run{ 2> allocate ch ...

  9. OSU!

    OSU! 首先,由题可知,本题是个期望题,根据期望的套路,定义f[x]为x前的答案,所以最终答案就是f[n] f[x]表示前x期望答案,即每一段的长度立方和的期望(一定要清楚) 但是三次方不好算,由于 ...

  10. HPS端的GPIO如何控制

    该笔记主要记录HPS端的GPIO如何控制,包括控制LED和Key 1.GPIO地址映射 Peripheral Base Address 0xf000_0000 64M 2.HPS外设 (1)GPIO ...