• 匈牙利算法


    题目链接: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;
    }
    
  • 相关阅读:
    迪杰斯特拉(Dijkstra)算法描述及理解
    KMP初步
    网络流初步
    Cutting Codeforces Round #493 (Div. 2)
    优先队列小结
    树状数组初步理解
    分块思想
    树状数组-逆序对-HDU6318
    线段树
    8.12.5
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262991.html
Copyright © 2020-2023  润新知