zoukankan      html  css  js  c++  java
  • 【模板】二分图匹配+构造+最大独立集——icpc PNWRC 2019

    求最大独立集,一般图的最大独立集复杂度是指数的,要想到怎么构造二分图

    由于每个字符串每个字符只出现一次(一开始没看到这个条件。。),所以可以按逆序对奇偶性来给点分组,构造二分图

    构造出二分图后,最大独立集=n-最大匹配数

    二分图匹配模板(O(nm)复杂度)

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 2e3 + 10;
    int n, m, e;
    vector<int> G[N];  //使用邻接表来储存边
    int match[N], vis[N];
    bool dfs(int u) {
      int len = G[u].size();
      for (int i = 0; i < len; i++) {  //遍历每一条边
        int v = G[u][i];
        if (vis[v]) continue;
        vis[v] = 1;
        if (!match[v] ||
            dfs(match[v])) {  //如果v没有匹配,或者v的匹配找到了新的匹配
          match[v] = u;
          match[u] = v;  //更新匹配信息
          return 1;
        }
      }
      return 0;
    }
    int main() {
      scanf("%d %d %d", &n, &m, &e);
      for (int i = 1; i <= e; i++) {
        int a, b;
        scanf("%d %d", &a, &b);
        if (a > n || b > m) continue;
        G[a].push_back(n + b);
        G[n + b].push_back(a);
      }
      int ans = 0;
      for (int i = 1; i <= n; i++) {  //对每一个点尝试匹配
        for (int j = 1; j <= n + m; j++) vis[j] = 0;
        if (dfs(i)) ans++;
      }
      printf("%d", ans);
      return 0;
    }
    View Code

    本题代码

    #include<bits/stdc++.h>
    using namespace std;
    #define N 505
    
    char s[N][N];
    vector<int>G[N],v1,v2;
    int n,vis[N],match[N];
    
    int calc(char s[],char t[]){//s交换两个字符,和t匹配 
        int tot=0,c1[N]={},c2[N]={},len=strlen(s+1);
        for(int i=1;i<=len;i++)
            c1[s[i]-'a']++,c2[s[i]-'a']++;
        for(int i=0;i<26;i++)
            if(c1[i]!=c2[i])return 0;
        for(int i=1;i<=len;i++)
            if(s[i]!=t[i])tot++;
        if(tot==0 || tot==2)return 1;
        return 0;
    }
    
    bool dfs(int u){
        for(auto v:G[u]){
            if(vis[v])continue;
            vis[v]=1;
            if(!match[v] || dfs(match[v])){
                match[v]=u;
                match[u]=v;
                return 1;
            }
        }
        return 0;
    }
    
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
        for(int i=1;i<=n;i++){
            int sum=0,len=strlen(s[i]+1);
            for(int j=1;j<=len;j++)
                for(int k=j+1;k<=len;k++)
                    if(s[i][j]>s[i][k])sum++;
            if(sum%2==0)v1.push_back(i);
            else v2.push_back(i);
        }
        
        for(auto u:v1)
            for(auto v:v2)
                if(calc(s[u],s[v])){
                    G[u].push_back(v);
                    G[v].push_back(u);
                }
        
        int ans=0;
        for(auto u:v1){
            memset(vis,0,sizeof vis);
            if(dfs(u))ans++;
        }
        
        cout<<n-ans<<'
    ';
    } 
  • 相关阅读:
    chgrp,chown,chmod用法
    关于linux文件夹与文件的权限理解
    centos7重置root密码
    Mac 下利用 Launchctl 自启动 mysql
    mac 10.10 下编译php拓展之mcrypt
    [转]使用Google地图API搜索功能
    ajax中获取和发送二进制数据的方法
    samba详解
    wamp You don't have permission to access / on this server等问题的解决.
    Cisco3.3.2.2
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12838674.html
Copyright © 2011-2022 走看看