Codeforce 403 D. Innokenty and a Football League

题意

对于一个球队有一个全名和家乡名
例如 DINAMO BYTECITY
他有两种缩写名字的方法
1.取全名的前三个字母即:DIN
2.全名的前两个字母和家乡名的第一个字母:DIB
如果有一个队伍按第二种方法取名即DIB,则其他队伍不可以通过第一种方式取名为DIN。(但可以通过第二种方法)

思路

<1>我们横容易发现上述的限制条件只针对两个全名的前三个字母相同的队伍,并且如果出现这种情况他们都不可以用第一种方式命名
<2>于是我们发现名称和队伍满足二分图的性质,于是我们可以O(N^2)的计算其最大匹配。

#include<bits/stdc++.h>
#define made(A) if(!mark[A])mark[A]=++num,R[num]=A;
#define P(a,b) G[a].push_back(b)
using namespace std;
typedef string S;
const int M=1e5+5;
map<S,int>mark;
bool use[M];
int has[2][M],T[M],n,num,cnt[M];
S A,B,N,H;
vector<int>G[M];
S R[M];
bool dfs(int x){
    for(int i=0;i<G[x].size();i++){
        int y=G[x][i];
        if(!use[y]){
            use[y]=1;
            if(T[y]==-1||dfs(T[y])){
                T[x]=y;T[y]=x;
                return 1;
            }
        }   
    }return 0;
}
inline int LM(){
    int ans=0;
    memset(T,-1,sizeof(T));
    for(int i=1;i<=n;i++)
        if(T[i]==-1){
            memset(use,0,sizeof(use));
            ans+=dfs(i);
        }
    return ans;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        cin>>N>>H;
        int a,b;
        A=N.substr(0,3);
        B=N.substr(0,2)+H[0];
        made(A);made(B);
        a=mark[A];b=mark[B];
        cnt[a]++;
        has[0][i]=a;
        has[1][i]=b;
    }
    for(int i=1;i<=n;i++){
        int a=has[0][i],b=has[1][i];
        if(cnt[a]<=1)P(i,a+n),P(a+n,i);
        P(i,b+n),P(b+n,i);
    }
    if(LM()==n){
        puts("YES");
        for(int i=1;i<=n;i++){
            int t=T[i]-n;
            cout<<R[t]<<endl;
        }
    }else puts("NO");
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值