• Problem F Plug It In!


    题目链接:https://cn.vjudge.net/contest/245468#problem/F

    大意:给你插座和电器的对应关系,有多个电器对应一个插座的情况,但是一个插座只能供一个电器使用,现在有一个转换头,能够将一个插座改成三个插头,问你最多能匹配多少个电器。

    思路: HK(洪凯)的思路。先按照没有转换头的思路跑一下匈牙利算法。然后,遍历有多个电器对应一个插座的这种情况,再“加”上两个插座,不过加上的这两个插座,对应关系和你当前正在遍历的这个插座与灯泡的对应关系相同,然后再看一下加入的这两个插座能不能匹配到灯泡,然后求出最大匹配量。

    代码:

    #include<iostream>
    #include<string>
    #include<cstring>
    #include<iomanip>
    #include<map>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<vector>
    using namespace std;
    #define maxn 1500+10
    int m,n,k;
    int vis[maxn];
    int net[maxn];
    int e[maxn];
    int a[maxn];
    vector<int >q[maxn];
    vector<int >wa[maxn];
    bool Find(int t)
    {
        int len=q[t].size();
        for(int i=0; i<len; i++)
        {
            int temp=q[t][i];
            if(vis[temp]==0)
            {
                vis[temp]=1;
                if(net[temp]==0||Find(net[temp]))
                {
                    net[temp]=t;
                    return true;
                }
            }
        }
        return false;
    }
    int match()
    {
        int ans=0;
        for(int i=1; i<=m; i++)
        {
            memset(vis,0,sizeof(vis));
            if(Find(i))ans++;
        }
        return ans;
    }
    int main()
    {
        memset(a,0,sizeof(a));
        memset(net,0,sizeof(net));
        cin>>m>>n>>k;
        for(int i=1; i<=k; i++)
        {
            int u,v;
            cin>>u>>v;
            q[u].push_back(v);//建立插座与灯泡的对应关系,方便后面的遍历。
            a[u]++;//记录插座对应的灯泡的个数
        }
        int t=match();
        // cout<<t<<endl;
        int maxx=0;
        for(int i=1; i<=n; i++)
        {
            e[i]=net[i];
        }
        for(int i=1; i<=m; i++)
        {
            if(a[i]>1)
            {
                int s=0;
                int len=q[i].size();
                for(int k=1; k<=2; k++)
                {
                    for(int j=0; j<len; j++)
                    {
                        int  temp=q[i][j];
                        q[m+k].push_back(temp);
                    }
                }//加上两个插座
                memset(vis,0,sizeof(vis));
                if(Find(m+1))s++;
                memset(vis,0,sizeof(vis));//注意每次对vis数组进行清空。
                if(Find(m+2))s++;
                maxx=max(s,maxx);
                q[m+1].clear();
                q[m+2].clear();//清除新加入的两个的插座的对应关系
                for(int l=1; l<=n; l++)
                {
                    net[l]=e[l];
                }//在匹配新加的两个插座的时候,原来的灯泡与插座的对应关系有可能会改变,所以需要恢复到原来的对应关系
                if(t==n)break;
            }
        }
        cout<<t+maxx<<endl;
        return 0;
    }
    
  • 相关阅读:
    pytorch 深度学习之数据操作
    pytorch 深度学习之微积分
    pytorch 深度学习之线性代数
    pytorch 深度学习之自动微分
    [Photoshop] ps中选区新建为图层的快捷键
    [Golang] Goland 编辑器 替换快捷键
    Go 自定义 Json 序列化规则
    MySQL入门篇(六)之mysqldump备份和恢复
    go panic 和 recover(重要)
    如何在 Linux 上模拟和缓解 DDoS 攻
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262945.html
Copyright © 2020-2023  润新知