1. 程式人生 > >POJ 2239 Selecting Course 二分圖匹配(水)

POJ 2239 Selecting Course 二分圖匹配(水)

return using div main str clu clas false hungary

http://poj.org/problem?id=2239

題意:總共7天,每天有12個教室使用,每門課有(t,pi,qi) 表示該門課每周開t次
在第qi天,第pi間教室i=1..t 總共n門課 n<=300,問最多能選多少種不同的課程?

左邊點為課程 右邊點為(p,q) 把(p,q)看成排列中的序數 化成整數(p-1)*12+q.
求二分圖的最大匹配即可 復雜度為O(nm)

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
const int N=3e2+20;
const int M=3e4;
int n,m;
int linker[M],vis[M];
int g[N][M];
bool dfs(int u)
{
	for(int i=1;i<=m;i++)
	{
		if(g[u][i]&&vis[i]==0)
		{
			vis[i]=1;
			//u-i ·??¥??±? i-linker[i]?a?¥??±? 
			//?òμ?·??¥??μ??ò??×??¥??±? 
			if(linker[i]==-1||dfs(linker[i])) 
			{
				linker[i]=u;
				return true;
			}
		}
	}
	return false;
}
int Hungary()
{
	int res=0;
	int u;
	memset(linker,-1,sizeof(linker));
	for(int i=1;i<=n;i++)
	{
		memset(vis,0,sizeof(vis));
		if(dfs(i))
			res++;
	}
	return res;
}
int main()
{
	while(cin>>n)
	{
		int u,v,t;
		m=7*12;
		memset(g,0,sizeof(g));
		for(int i=1;i<=n;i++)
		{
			cin>>t;
			for(int j=1;j<=t;j++)
			{
				cin>>u>>v;
				g[i][(u-1)*12+v]=1;
			}	
		}
		int ans=Hungary();
		cout<<ans<<endl;
	}
	
	return 0;
}

  

POJ 2239 Selecting Course 二分圖匹配(水)