A. Alien Communication Masterclass
【题目】
给定序列A、B,构造一个等式,使得对于任意的A[i]进制都满足,对于任意的B[i]都
不满足
【分析i】
同一个式子,不同进制的结果如果不相同,一般是在进位上,首先我们可以想到如
果对于A序列的进制都满足呢,可以写成x1 * x2 * x3 *x4 = 0这种,每种进制可以构
造一个等于0的式子,对于A[i],可以构造(10 - 1 - 1 - 1…. - 1)共减去a[i]个1
B .Flowery Trails
【问题】
给定一无向图,询问由s至t的所有最短路径的边的并
【分析】
从s开始跑一遍最短路,从t开始跑一遍最短路,然后一次枚举每条边,判断是否是最
短路径上的边
C. Commuting Functions
【问题】
已知两函数f、g满足f[g[x]] = g[f[x]],函数f的定义域、值域都为1~n的整数,且f为双
射函数,询问函数g的值(字典序尽可能的小)
【分析】
显然f的值域是由若干循环节组成的,对于一个循环节来说,g中对应位置也为循环
节,且只要此循环节的一个数值确定,那么整个循环节便确定下来了,为了保证字
典序尽可能的小,我们应该让此循环节的最靠左的位置对应的数尽可能的小。
首先,对于f的一个长度为k的循环节,假如之前没有出现过长度为k的因子的循环
节,那么对于此 ,g[i]= i是显然可行的一个方案,并且是字典序最小的方案,那么
长度为2* k也可以使用此方案,3* k也可以使用此方案。
因此对于f的每个值,判断他的循环节长度k,找出最靠左的位置应该填充的数值,依
次填取即可
D.Book Club
【题目】
给定一有向图,询问是否存在若干环,使得这些环把每个顶点包含一次,其实说白
了就是二分图最大匹配
【分析】
直接用匈牙利算法搞一下就可以了,说一下匈牙利的原理吧,对于每个小哥哥,都
会尽可能的找到一个小姐姐与之对应,如果给某个小哥哥A找的过程中,发现他想找
的小姐姐A已经被小哥哥B抢了,这时候判断一下能否给小哥哥B换一个小姐姐,这
样岂不是两全其美,判断的时候对小姐姐A做一个标记,发表已经试图从小姐姐A这
腾一个位置,这样以后就不需要再次在小姐姐A上考虑了
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int N = 10000 + 500;
vector<int > s[N];
int tmp[N];
bool f[N];
bool dfs(int x)
{
for(int i = 0; i < s[x].size(); i++)
{
int y = s[x][i];
if (!f[y])
{
f[y] = true;
if (tmp[y] == -1 || dfs(tmp[y]))
{
tmp[y] = x;
return 1;
}
}
}
return 0;
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
s[x].push_back(y);
}
memset(tmp, -1, sizeof(tmp));
for(int i = 0; i < n; i++)
{
memset(f, 0, sizeof(f));
dfs(i);
}
bool delta = true;
for(int i = 0; i < n; i++)
if(tmp[i] == -1)
{
delta = false;
break;
}
if (delta)
printf("YES\n"); else
printf("NO\n");
return 0;
}