2019CCPCharbin F - Fixing Banners(dfs/匈牙利匹配)

题意:给六个字符串每个字符串选一个字母组成“harbin”

思路:当时看到这题时我第一感觉是dfs,队友cg因为刚刚学过匈牙利匹配大喊这是匈牙利匹配,好像还吓到了隔壁桌的朋友,不过在cg再抄了许久板子之后发现板子有问题。。。最后还是用dfs过的。补题时也是用dfs写,但是发现如果剪枝不彻底会T,如今在学了匈牙利匹配后(发现其实不是很难的算法),又用匈牙利匹配a了一发,理论上匈牙利复杂度最坏6^3,dfs最坏6!,最后两种算法时间也差不多。我在下面把两种写法都贴出来

匈牙利写法

#include <bits/stdc++.h>
#define x first
#define y second
#define mid (l + r >> 1)
#define lo (o << 1)
#define ro (lo | 1)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 998244353;
struct tri{int x,y,z;};
string harbin="harbin";
bool edg[6][6],vis[6];
int linker[6];

bool dfs(int u)
{
    for(int v=0;v<6;v++)if(edg[u][v]&&!vis[v])
    {
        vis[v]=1;
        if(linker[v]==-1||dfs(linker[v]))
        {
            linker[v]=u;
            return 1;
        }
    }
    return 0;
}

bool solve()
{
    memset(edg,0,sizeof(edg));
    memset(linker,-1,sizeof(linker));
    for(int i=0;i<6;i++)
    {
        string s;cin>>s;
        for(auto j:s)for(int k=0;k<6;k++)
            if(j==harbin[k])edg[i][k]=1;
    }//建图
    int ans=0;
    for(int i=0;i<6;i++)
    {
        memset(vis,0,sizeof(vis));
        if(dfs(i))ans++;
    }
    return ans==6;
}
 
int main()
{
    // freopen("in.txt","r",stdin);
    int _;cin>>_;
    while(_--)
    {
        if(solve())puts("Yes");
        else puts("No");
    }
    return 0;
}

DFS写法

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef float ld;
const int maxn=1e5+10;
const int inf=0x3f3f3f3f;
const char harbin[10]={"harbin"};
 
int boa[6][6],vis[6];
 
bool dfs(int step)
{
    if(step==6)return 1;
    for(int i=0;i<6;i++)
    {
        if(boa[step][i]&&vis[i]==0)
        {
            vis[i]=1;
            if(dfs(step+1))
            {
                return 1;
            }
            vis[i]=0;
        }
    }
    return 0;
}
 
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(boa,0,sizeof(boa));
        memset(vis,0,sizeof(vis));
        string s[6];
        for(int i=0;i<6;i++)
            cin>>s[i];
        for(int i=0;i<6;i++)
        {
            for(int j=0;j<s[i].length();j++)
            {
                for(int k=0;k<6;k++)
                {
                    if(harbin[k]==s[i][j])boa[i][k]=1;
                }
            }
        }
 
        if(dfs(0))puts("Yes");
        else puts("No");
    }
 
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43700916/article/details/104237410
F