匈牙利算法

题目链接: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;
}

 

posted @ 2018-07-23 14:17  Let_Life_Stop  阅读(214)  评论(0编辑  收藏  举报