• 洛谷P1640 连续攻击游戏+二分图匹配


    本题是个二分图匹配问题。
    首先我们来复习一下匈牙利算法:
    用临接矩阵写的匈牙利:
    Code:(洛谷P3386)

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    #define INF 0x3f3f3f3f
    #define maxn 1001
    using namespace std;
    int match[maxn*100],n,m,e,ans,map[maxn][maxn],vis[maxn*100];
    bool dfs(int x){
        for(int i=1;i<=m;i++){
            if(map[x][i]==1&&vis[i]==0){
                vis[i]=1;
                if(match[i]==0||dfs(match[i])==1){
                    match[i]=x;
                    return 1;
                }
            }
        }
        return 0;
    }
    int main(){
        cin>>n>>m>>e;
        for(int i=1;i<=e;i++){
            int x,y;
            cin>>x>>y;
            if(x<=n&&y<=m){
                map[x][y]=1;
            }
        }
        for(int i=1;i<=n;i++){
            memset(vis,0,sizeof(vis));
            if(dfs(i)==1){
                ans++;
            }
        }
        cout<<ans;
        return 0;
    }

    现在我们来看这个题:
    把物品属性a,b,从a,b向i连个有向边,然后一部分是物品一部分是序号,直接匹配即可。
    Code:

    // luogu-judger-enable-o2
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #define ll long long
    #define maxn 100010
    using namespace std;
    struct Edge{
        int nxt,to;
    }edge[2000010];
    int n,num_edge,ans,vis[10005],head[10005],match[1000010];
    inline void addedge(int from,int to){
        edge[++num_edge].to=to;
        edge[num_edge].nxt=head[from];
        head[from]=num_edge;
    }
    bool dfs(int x){
        if(vis[x]) return 0;
        vis[x]=1;
        for(int i=head[x];i;i=edge[i].nxt){
            int y=edge[i].to;
        //    if(!vis[y]){
        //        vis[y]=1;
                if(!match[y]||dfs(match[y])){
                    match[y]=x;
                    return 1;
                }
        //    }
        }
        return 0;
    }
    inline void check(){
        for(int i=1;i<=n;i++){
            memset(vis,0,sizeof(vis));
            if(dfs(i)){
                ans++;
            }
            else break;
        }
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            //addedge(x,y);
            addedge(x,i);
            addedge(y,i);
        }
        check();
        printf("%d",ans);
        return 0;
    } 
  • 相关阅读:
    按之字形打印二叉树 --剑指offer
    浅谈PHP+Access数据库的连接 注意要点
    Linux下统计代码行数
    获取服务器IP,客户端IP
    CURL访问举例
    廖雪峰博客
    Redis命令
    svn merge和branch 详解
    Linux Screen超简明教程
    MySQL 的Coalesce函数
  • 原文地址:https://www.cnblogs.com/kenlig/p/9822597.html
Copyright © 2020-2023  润新知