考试11.6 T2 匈牙利 + 二分

来源:互联网 发布:淘宝c店未来发展 编辑:程序博客网 时间:2024/06/10 05:36

这里写图片描述
这里写图片描述

出题人的语文不错啊~~~~

二分后跑匈牙利;

考试的时候打错了变量名全WA,竟然还过了样例!!!!

注意二分边界,因为是左闭右开区间,所以r需要加1;

#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;const int MAXN=400001;int fst[MAXN],nxt[MAXN],cdis[MAXN];struct hh {int from,to;}ma[MAXN];bool vis[MAXN][31],used[MAXN];int T,n,l,r,tot,cnt;char ss[1001],s[1001][1001];void build(int f,int t){    ma[++tot]=(hh){f,t};    nxt[tot]=fst[f],fst[f]=tot;    return;}bool dfs(int x){    for(int i=fst[x];i;i=nxt[i])    {        int v=ma[i].to;        if(!used[v])        {            used[v]=1;            if(!cdis[v] || dfs(cdis[v]))            {                cdis[v]=x;                return true;            }        }    }    return false;}bool check(int x){    memset(fst,0,sizeof(fst));    memset(nxt,0,sizeof(nxt));    memset(ma,0,sizeof(ma));    memset(cdis,0,sizeof(cdis));    memset(used,0,sizeof(used));    tot=0,cnt=0;    for(int j=1;j<=x;j++)        for(int i=1;i<=n;i++)            if(vis[i][ss[j]-'A'+1])                build(j,i);    for(int i=1;i<=x;i++)    {        memset(used,0,sizeof(used));        if(dfs(i)) cnt++;    }    if(cnt==x) return true;    else return false;}void solve(){    memset(vis,0,sizeof(vis));    memset(ss,'\0',sizeof(ss));    scanf("%d",&n);    for(int i=1;i<=n;i++) scanf("%s",s[i]+1);    scanf("%s",ss+1);    for(int i=1;i<=n;i++)    {        int len=strlen(s[i]+1);        for(int j=1;j<=len;j++)            vis[i][s[i][j]-'A'+1]=1;    }    r=strlen(ss+1)+1,l=0;    while(r - l > 1)    {        int mid=(l+r)>>1;        if(check(mid)) l=mid;        else r=mid;    }    cout<<l<<'\n';}int main(){    cin>>T;    while(T--) solve();    return 0;}
原创粉丝点击