SRM589 Div1Medium GearsDiv1

来源:互联网 发布:阿里云服务器端口映射 编辑:程序博客网 时间:2024/06/07 05:28

【分析】
一共才三种颜色,所以旋转的方向也就两种:
1、顺,顺,顺
2、顺,顺,逆
顺和逆当然可以交换。
同时,三个顺时针一定不优于两顺一逆。(因为这就要求剩下的齿轮都不能接触)
所以我们枚举是哪两种齿轮是顺时针。
这就符合二分图的定义了:同一种颜色一定不会咬合(没有边),不同种颜色会存在一些边。
而题目求的是最少要删多少个齿轮。在二分图中有边相连的两个齿轮至少要删掉一个。
所以题目就转化成二分图的最大匹配了。

【代码】

#include <bits/stdc++.h>using namespace std;#define M 55int n;char str[M];bool hav[M][M];bool mk[M];int to[M];void chk(int &x,int y){    if(x>y)x=y;}bool find(char A,char B,int x){    for(int i=1;i<=n;i++){        if(str[i]!=B)continue;        if(!hav[x][i]||mk[i])continue;        mk[i]=1;        if(to[i]==-1||find(A,B,to[i])){            to[i]=x;            return 1;        }    }    return 0;}int Flow(char A,char B){    int mx=0;    memset(to,-1,sizeof(to));    for(int i=1;i<=n;i++){        if(str[i]!=A)continue;        memset(mk,0,sizeof(mk));        mx+=find(A,B,i);    }    return mx;}int main(){    scanf("%d",&n);    scanf("%s",str+1);    for(int i=1;i<=n;i++){        char mp[M];        scanf("%s",mp+1);        for(int j=1;j<=n;j++){            if(mp[j]=='Y')hav[i][j]=1;        }    }    int ans=n;    chk(ans,Flow('R','G'));    chk(ans,Flow('R','B'));    chk(ans,Flow('B','G'));    printf("%d\n",ans);    return 0;}
1 0