匈牙利算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2063
题目大意:求二分图的最大分配
代码:
#include<bits/stdc++.h>
using namespace std;
int k,n,m;
# define maxn 510
int line[maxn][maxn],Exit[maxn],net[maxn];
bool Find(int t){
for(int i=1;i<=m;i++){
if(line[t][i]&&Exit[i]==0){
Exit[i]=1;
if(net[i]==0||Find(net[i])){
net[i]=t;
return true;
}
}
}
return false;
}
int match(){
int ans=0;
for(int i=1;i<=n;i++)
{
memset(Exit,0,sizeof(Exit));
if(Find(i))ans++;
}
return ans;
}
int main(){
while(cin>>k&&k){
cin>>n>>m;
memset(line,0,sizeof(line));
//memset(Exit,0,sizeof(Exit));
memset(net,0,sizeof(net));
for(int i=1;i<=k;i++){
int u,v;
cin>>u>>v;
line[u][v]=1;
}
int t=match();
cout<<t<<endl;
}
return 0;
}
vector版
#include<bits/stdc++.h>
using namespace std;
# define maxn 1010
int s1[maxn],s2[maxn];
int line[maxn][maxn],net[maxn],Exit[maxn];
vector<int>wakaka[maxn];
int t;
int n,m;
bool Find(int x)
{
int len=wakaka[x].size();
for(int i=0; i<len; i++)
{
if(!Exit[wakaka[x][i]])
{
Exit[wakaka[x][i]]=1;//注意vector版的Exit数组的下标和用数组做的区别。
if(net[wakaka[x][i]]==0||Find(net[wakaka[x][i]]))
{
net[wakaka[x][i]]=x;
return true;
}
}
}
return false;
}
int match()
{
int ans=0;
for(int i=1; i<=n; i++)
{
memset(Exit,0,sizeof(Exit));
if(Find(i))ans++;
}
return ans;
}
int main()
{
while(cin>>t&&t)
{
cin>>n>>m;
for(int i=1; i<=1010; i++)
{
wakaka[i].clear();
}
//memset(line,0,sizeof(line));
memset(net,0,sizeof(net));
//memset(s1,0,sizeof(s1));
//memset(s2,0,sizeof(s2));
for(int i=1; i<=t; i++)
{
int u,v;
cin>>u>>v;
wakaka[u].push_back(v);
}
int s=match();
cout<<s<<endl;
}
return 0;
}
//////////////////////////////////////////更新
较难题目(最近打比赛做到的题)
https://cn.vjudge.net/contest/245385#problem/J
代码:
#include<iostream>
#include<string>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stdio.h>
using namespace std;
# define maxn 200+10
int n,m;
int a[maxn][maxn];
int vis[maxn];
int net[maxn];
int u[maxn],v[maxn];
bool Find(int t)
{
for(int i=1; i<=m; i++)
{
if(vis[i]==0&&a[t][i])
{
vis[i]=1;
if(net[i]==0||Find(net[i]))
{
net[i]=t;
return true;
}
}
}
return false;
}
int f(int t)
{
int sum=0;
while(t!=0)
{
sum+=t%10;
t=t/10;
}
return sum;
}
int match()
{
int ans=0;
memset(net,0,sizeof(net));
for(int i=1; i<=n; i++)
{
memset(vis,0,sizeof(vis));
if(Find(i))ans++;
}
return ans;
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
memset(a,0,sizeof(a));
cin>>n>>m;
for(int i=1; i<=n; i++) cin>>u[i];
for(int i=1; i<=m; i++) cin>>v[i];
for(int i=1; i<=n; i++)
{
int t1=u[i]/1000;
for(int j=1; j<=m; j++)
{
int t2=v[j]%1000;
if(f(t1)==f(t2))
{
a[i][j]=1;//注意建图方式,不能建立双向图
}
}
}
for(int i=1; i<=m; i++)
{
int t1=v[i]/1000;
for(int j=1; j<=n; j++)
{
int t2=u[j]%1000;
if(f(t1)==f(t2))
{
a[j][i]=2;
}
}
}
int t=match();
cout<<t<<endl;
for(int i=1; i<=m; i++)
{
if(net[i])
{
if(a[net[i]][i]==1)
{
cout<<"AT"<<" "<<u[net[i]]<<" "<<v[i]<<endl;
}
else
{
cout<<"TA"<<" "<<v[i]<<" "<<u[net[i]]<<endl;
}
}
}
return 0;
}