Description
Input
Output
Sample Input
5 1 1 1 2 1 1 2 2 1 2 2 2 3 2 3 3 1 3 3
Sample Output
4
这题刚开始理解题目错了,尼玛,看到样例中1 1有几个,所以还以为是重复的呢,就只取了一个,然后就剩下(1,1),(2,2),(3,2),(3,3),然后就得出样例答案为4.。直接WA一发,然后又重新读题才发现理解错题意了,晕……
题意原来是当前课程会在那些时间上几次课,刚开始因为当前是一个结点了,然后周数与节数又有两个数据,所以想想这两个如果要想放在图论中,那么当然得把这两个数据合成一个地址……哈哈这么想着就有思路了……因为以前做过哈希方面的题,所以保存了好多哈希取址的计算函数,在实际中用得最多最高效也是最容易的就是BKDRHash哈希函数了,其计算式为:a*131+b这个就作为一个新地址存下来,也就是另一个结点……因为这个计算式已经被好多人证实过了,对于全部的(a,b),其取唯一地址的函数可以用这个计算,这个函数在实际中也是证明被用得最多的了,当然这个没有处理地址冲突,所以地址还是有bug的,但是就这水题这个式子够了……
然后有了这两个结点当然就可以做边了,匹配就是二分匹配了……
哈希不懂的可以看我的另一篇博文:http://blog.csdn.net/u011466175/article/details/17484687
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <list>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define PI acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define sca(a) scanf("%d",&a)
#define pri(a) printf("%d\n",a)
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define MM 1000005
#define MN 100010
#define INF 55566677
#define eps 1e-7
using namespace std;
typedef long long ll;
vector<int>v[MN];
int vis[MN],pre[MN];
int dfs(int u)
{
for(int i=0; i<v[u].size(); i++)
{
int j=v[u][i];
if(!vis[j])
{
vis[j]=1;
if(!pre[j]||dfs(pre[j]))
{
pre[j]=u;
return 1;
}
}
}
return 0;
}
int solve(int n)
{
int ans=0;
for(int i=1; i<=n; i++)
{
mem(vis,0);
ans+=dfs(i);
}
return ans;
}
int main()
{
int n,m,i,j,p,q;
while(~sca(n))
{
for(i=0;i<=n;i++) v[i].clear();
mem(pre,0);
for(i=1;i<=n;i++)
{
sca(m);
while(m--)
{
scanf("%d%d",&p,&q);
int cnt=p*131+q;//BKDRHash哈希取址计算式即可
v[i].push_back(cnt);
}
}
pri(solve(n));
}
return 0;
}
POJ 2239 哈希取址+二分匹配,布布扣,bubuko.com
原文:http://blog.csdn.net/u011466175/article/details/22698975