zoukankan      html  css  js  c++  java
  • 二分图

     

    几个二分图性质:

    1. 最小点覆盖 等于 最大匹配,

    最小点覆盖,实际上就是说选取最少的点,使得图中所有的边都与之相关联。

    2. 最大独立集  等于 总点数 - 最小点覆盖。

    最大独立集:就是选取一个最大的集合,使得集合的点之间,两两无对应边相连。

    3.最小不相交路径覆盖 等于 顶点数 -  最大匹配。

    最小边覆盖,在一个DAG中,选取最少的,顶点不相交的路径,覆盖图里所有的点

    过山车

     HDU - 2063 

    模板,分析匈牙利算法,其实就是找得到就匹配,找不到这个点换一下看看能不能匹配;

    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    const int N=6e2+5;
    vector<int>e[N];
    int match[N];
    bool vis[N];
    bool findpath(int u){
        for(int i=0;i<e[u].size();i++){
        int v=e[u][i];
        if(!vis[v]){
        vis[v]=1;
        if(!match[v]||findpath(match[v])){
        match[v]=u;
        return 1;
        }
        }
        }
        return 0;
    }   
    int main(){
        int k,m,n;
        while(~scanf("%d",&k),k){
        scanf("%d %d",&m,&n);
        for(int i=0;i<=N;i++)match[i]=0,e[i].clear();
        // girl.clear();
        for(int i=1,u,v;i<=k;i++){
        scanf("%d %d",&u,&v);e[u].pb(v);
        // girl.pb(u);
        }
        int ans=0;
        for(int i=1;i<=m;i++){
        memset(vis,0,sizeof vis);
        if(findpath(i))ans++;        
        }
        // cout<<"test"<<endl;
        printf("%d
    ",ans);
    
        }
        // system("pause");
        return 0;
    }
    View Code

    Asteroids

     POJ - 3041 

    题意:n*n的网格,有k个障碍,每次可以把某一行或者某一列删掉,求最小操作次数。

    做法;对于给定的图,把每一行,每一列抽象为点,每一个障碍点(x,y),实际上可以抽象为 x 到 y 有一条边。

    求最小操作次数,实际上就是求最小点覆盖。

    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define pb push_back
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    typedef long long ll;
    typedef double db;
    const int N=5e2+50;
    int gp[N][N];
    int match[N],vis[N];
    int n,m,k;
    void init(){
        memset(match,0,sizeof match);
        // memset(vis,0,sizeof vis);
        memset(gp,0,sizeof gp);
    
    }
    bool findpath(int u){
        for(int i=1;i<=n;i++){
            if(gp[u][i]&&!vis[i]){
                vis[i]=1;
                if(!match[i]||findpath(match[i])){
                    match[i]=u;
                    return 1;
                }
            }
        }
        return 0;
    }
    int main(){
        init();
        scanf("%d %d",&n,&k);
        for(int i=1,u,v;i<=k;i++){
            scanf("%d %d",&u,&v);
            gp[u][v]=1;
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            memset(vis,0,sizeof vis);
            if(findpath(i))ans++;
        }
        // cout<<ans<<endl;
        printf("%d
    ",ans);
        // system("pause");
        return 0;
    }
    View Code

    Air Raid

     POJ - 1422 

    题意:一张图,求最小不相交路径覆盖,

    #include<cstdio>
    #include<cstring>
    // #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    typedef long long ll;
    typedef double db;
    const int N=5e2+50;
    int gp[N][N];
    int match[N],vis[N];
    int n,m,k;
    void init(){
        memset(match,0,sizeof match);
        // memset(vis,0,sizeof vis);
        memset(gp,0,sizeof gp);
    
    }
    bool findpath(int u){
        for(int i=1;i<=n;i++){
            if(gp[u][i]&&!vis[i]){
                vis[i]=1;
                if(!match[i]||findpath(match[i])){
                    match[i]=u;
                    return 1;
                }
            }
        }
        return 0;
    }
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
    
         init();
        scanf("%d %d",&n,&k);
        for(int i=1,u,v;i<=k;i++){
            scanf("%d %d",&u,&v);
            gp[u][v]=1;
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            memset(vis,0,sizeof vis);
            if(findpath(i))ans++;
        }
        // cout<<ans<<endl;
        printf("%d
    ",n-ans);
        }
        // system("pause");
        return 0;
    }
    View Code

    Guardian of Decency

     POJ - 2771 

    一些男孩和女孩有暧昧关系,选出一个最大集,使得两两之间没有恋爱关系。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    #define pb push_back
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    typedef long long ll;
    typedef double db;
    const int N=5e2+50;
    int gp[N][N],match[N],vis[N];
    int n,m;
    void init(){
        
        memset(gp,0,sizeof gp);
        
        memset(match,0,sizeof match);
    
        n=m=0;
    
    }
    
    struct node{
    
        int h;
        
        string sex,mus,spo;
    
    }boy[N],girl[N];
    
    bool check(node a,node b){
        if(fabs(a.h-b.h)<=40&&a.sex!=b.sex&&a.mus==b.mus&&a.spo!=b.spo)return 1;
        return 0;
    }
    
    bool findpath(int u){
        for(int i=1;i<=m;i++){
            if(gp[u][i]&&!vis[i]){
                vis[i]=1;
                if(!match[i]||findpath(match[i])){
                    match[i]=u;
                    return 1;
                }
            }
        }
        return 0;
    }
    int main(){
        int t,num;
        scanf("%d",&t);
        while(t--){
            scanf("%d",&num);
            node tmp;
            init();
            for(int i=1;i<=num;i++){
                cin>>tmp.h>>tmp.sex>>tmp.mus>>tmp.spo;
                if(tmp.sex=="M")boy[++n]=tmp;
                else girl[++m]=tmp;
            }
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    if(check(boy[i],girl[j]))gp[i][j]=1;
                }
            }
            int ans=0;
            for(int i=1;i<=n;i++){
                memset(vis,0,sizeof vis);
                if(findpath(i))ans++;
            }
            printf("%d
    ",num-ans);
    
        }
        // system("pause");
        return 0;
    }
    View Code
    想的太多,做的太少;
  • 相关阅读:
    可搜索的下拉框
    Vue 父组件调用子组件的方法
    vue中异步函数async和await的用法
    用配置文件的方法发送axios请求
    vue中 localStorage的使用方法(详解)
    下拉框 组件的使用
    遇到不懂的记录
    做测试平台可能会用到的东西
    下拉框 v-for循环拿值的方法
    ant 自定义遮罩
  • 原文地址:https://www.cnblogs.com/littlerita/p/12457992.html
Copyright © 2011-2022 走看看