Topcoder12729 「SRM589Medium」GearsDiv1 二分图最大匹配
Posted liubainian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Topcoder12729 「SRM589Medium」GearsDiv1 二分图最大匹配相关的知识,希望对你有一定的参考价值。
问题描述
(N) 个齿轮每个齿轮有颜色(RGB),有些齿轮之间会咬合,你需要删除尽量少的齿轮并给每种颜色安排方向使得咬合齿轮不同向。问最多保留多少个齿轮。保证不存在两个相同颜色的齿轮咬合。
交互输入输出大毒瘤!
题解
发现对于 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
",to[i^1],to[i],w[i]);
}
printf("## S = %d , T = %d
",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
",maxflow);
Graph_build(2);
int tmp=Dinic();
maxflow=min(maxflow,tmp);
// printf("** %d
",tmp);
Graph_build(3);
tmp=Dinic();
maxflow=min(maxflow,tmp);
// printf("** %d
",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 二分图最大匹配的主要内容,如果未能解决你的问题,请参考以下文章