一道二份匹配的题目,
1672 | Cuckoo Hashing |
也是湖大上的一道题,在湖大提交通过,以为在杭电就顺理成章可以了,可笑的是屡交都是tle。
原来时间要求不同,在湖大5000ms,而杭电1000 ms,我倒啊@
经过修改发现一个改进点,找增广路径时性能可以优化,因为每个左边的点都只对应两个右边点。
改进后却还是只从3534ms降到1992ms,还是不行。
寻思许久,只好灵光一闪试着把cin cout 换成printf 和scnaf,最后一场激动终于发现了,好郁闷啊。
第一次遇到输出输入的影响,也许是一次提醒。。。谨记。。。
c++实现
#include <iostream>
using namespace std;
//2008.4.18
//一个二分匹配的问题
//不过每个左结点的连接边都为2
int zimu[10000][2];
bool taket[10000];
int to[10000];
int ln;
int rn;
bool canfind(int t)
{
int i;
for(i = 0; i < 2; ++i) //这是较大的改进,否则0到rn超时
{
if(!taket[zimu[t][i]])
{
taket[zimu[t][i]] = true;
if(to[zimu[t][i]] == -1 || canfind(to[zimu[t][i]]) )
{
to[zimu[t][i]] = t;
return true;
}
}
}
return false;
}
void Hashing()
{
int t;
//cin >> t;
scanf("%d", &t);
while(t--)
{
//cin >> ln >> rn;
scanf("%d%d", &ln, &rn);
int i;
for(i = 0; i < ln; ++i)
{
//cin >> zimu[i][0] >> zimu[i][1];
scanf("%d%d", &zimu[i][0], &zimu[i][1]);
}
memset(to, -1, sizeof(to));
int flag = 1;
for(i = 0; i < ln; ++i)
{
memset(taket, 0, sizeof(taket));
if(!canfind(i))
{
flag = 0;
//cout << "rehash necessary" << endl;
printf("rehash necessary/n");
break;
}
}
if(flag == 1)
//cout << "successful hashing" << endl;
printf("successful hashing/n");
}
}
int main()
{
Hashing();
return 0;
}