2019 CCPC 哈尔滨 - F Fixing Banners(二分图)

题目描述
Harbin, whose name was originally a Manchu word meaning “a place for drying fishing nets”, grew from a small rural settlement on the Songhua River to become one of the largest cities in Northeast China. Founded in 1898 with the coming of the Chinese Eastern Railway, the city first prospered as a region inhabited by an overwhelming majority of the immigrants from the Russian Empire. Now, Harbin is the capital of Heilongjiang province and the largest city in the northeastern region of the People’s Republic of China. It serves as a key political, economic, scientific, cultural, and communications hub in Northeast China, as well as an important industrial base of the nation.

This year, a CCPC regional contest is going to be held in this wonderful city, hosted by Northeast Forestry University. To ensure the contest will be a success and enjoyed by programmers around the country, preparations for the event are well underway months before the contest.

You are the leader of a student volunteer group in charge of making banners to decorate the campus during the event. Unfortunately, your group made a mistake and misprinted one of the banners. To be precise, the word “harbin” is missing in that banner. Because you don’t have time to reprint it, the only way to fix it is to cut letters from some used old banners and paste them onto the misprinted banner. You have exactly six banners, and for some reason, you must cut exactly one letter from each banner. Then, you can arrange and paste the six letters onto the misprinted banner and try to make the missing word “harbin”. However, before you start cutting, you decide to write a program to see if this is possible at all.

Input
The input contains multiple cases. The first line of the input contains a single integer T (1≤T≤50000), the number of cases.

For each case, the input contains six lines. Each line contains a non-empty string consisting only of lowercase English letters, describing the letters on one of the old banners.

The total length of all strings in all cases doesn’t exceed 2⋅106.

Output
For each case, print the string “Yes” (without quotes) if it is possible to make the word “harbin”, otherwise print the string “No” (without quotes).

Example
Input
2
welcome
toparticipate
inthe
ccpccontest
inharbin
inoctober
harvest
belong
ninja
reset
amazing
intriguing
Output
No
Yes
解题思路: 这题写完后才发现大家都是用的dfs和部分状压dp过的,这题要每个字符串对应的一个字母,直接二分图行列模型,板子题,每行匹配一个(一列)。
贡献一波二分图解法
Code

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const int maxn = 2e6+7 ;
const ll mod = 1000000007;

#define mst(x, a) memset( x,a,sizeof(x) )
#define rep(i, a, b) for(int i=(a);i<=(b);++i)
#define dep(i, a, b) for(int i=(a);i>=(b);--i)

inline ll read() {
	ll x = 0;
	bool f = 0;
	char ch = getchar();
	while (ch < '0' || '9' < ch)
		f |= ch == '-', ch = getchar();
	while ('0' <= ch && ch <= '9')
		x = x * 10 + ch - '0', ch = getchar();
	return f ? -x : x;
}

void out(ll x) {
	int stackk[20];
	if (x < 0) {
		putchar('-');
		x = -x;
	}
	if (!x) {
		putchar('0');
		return;
	}
	int top = 0;
	while (x)
		stackk[++top] = x % 10, x /= 10;
	while (top)
		putchar(stackk[top--] + '0');
}
int link[9][9],use[9],g[9],n;
int find(int x)
{
    for(int i=1 ;i<=6 ;i++)
    {
        if(use[i]==0&&link[x][i])
        {
            use[i]=1;
            if(g[i]==0||find(g[i]))
            {
                g[i]=x;
                return 1;
            }
        }
    }
    return 0;
}
int main() {
  
 int otot=read();
  while(otot--)
  {
 //   n=read();
    mst(g,0);
    mst(link,0);
    mst(use,0);
    for(int i=1 ;i<=6 ;i++)
    {
        string  s;
        cin>>s;
        for(int j=0 ;j<s.size();j++)
        {
            if(s[j]=='h') link[i][1]=1;
             if(s[j]=='a') link[i][2]=1;
             if(s[j]=='r') link[i][3]=1;
             if(s[j]=='b') link[i][4]=1;
             if(s[j]=='i') link[i][5]=1;
             if(s[j]=='n') link[i][6]=1;
        }
    }
    int ans=0;
    for(int i=1 ;i<=6 ;i++)
    {
        mst(use,0);
        if(find(i)) ans++;
    }
     if(ans==6) puts("Yes");
     else puts("No");
  }
	return 0;
}

/*


*/
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值