训练指南 UVALive - 3415(最大点独立集)



layout: post
title: 训练指南 UVALive - 3415(最大点独立集)
author: "luowentaoaa"
catalog: true
mathjax: true
tags:
- 二分图
- 图论
- 训练指南


Guardian of Decency

UVALive - 3415

我们将男女分开来 就可以建出一个二分图,对于任意的男女生 只要上边四个条件一个也不满足 就表示不能同时去 ,那么我们在其中间连一条边,那么最终的结果就是我们从中取出尽量多的点,使得任意两个点之间没有连线。那么问题就转化成了求最大点独立集。 二分图的最大点独立集= 总点数 - 最大匹配(最小点覆盖)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=1e3+50;
const ll inf=1e10;
const ll INF = 1000000000;
const double eps=1e-5;
#define bug cout<<"bbibibibbbb="<<endl;
/// 二分图最大基数匹配
struct BPM{
    int n,m;    /// 左右顶点个数
    int G[maxn][maxn]; /// 邻接表
    int left[maxn];    /// left[i]为右边第i个点的匹配点编号,-1表示不存在
    bool T[maxn];       /// T[i]为右边第i个点是否已标记

    int right[maxn];        /// 求最小覆盖用
    bool S[maxn];           /// 求最小覆盖用

    void init(int n,int m){
        this->n=n;
        this->m=m;
        memset(G,0,sizeof(G));
    }

   /* void AddEdge(int u,int v){
        G[u].push_back(v);
    }*/

    bool match(int u){
        S[u]=true;
        for(int v=0;v<m;v++){
            //int v=G[u][i];
            if(G[u][v]&&!T[v]){
                T[v]=true;
                if(left[v]==-1||match(left[v])){
                    left[v]=u;
                    right[u]=v;
                    return true;
                }
            }
        }
        return false;
    }
    /// 求最大匹配
    int solve(){
        memset(left,-1,sizeof(left));
        memset(right,-1,sizeof(right));
        int ans=0;
        for(int u=0;u<n;u++){
            memset(S,0,sizeof(S));
            memset(T,0,sizeof(T));
            if(match(u))ans++;
        }
        return ans;
    }
    /// 求最小覆盖。X和Y为最小覆盖中的点集
    int mincover(vector<int>& X,vector<int>& Y){
        int ans=solve();
        memset(S,0,sizeof(S));
        memset(T,0,sizeof(T));
        for(int u=0;u<n;u++)
            if(right[u]==-1)match(u);
        for(int u=0;u<n;u++)
            if(!S[u])X.push_back(u);
        for(int v=0;v<n;v++)
            if(T[v])Y.push_back(v);
        return ans;
    }
};
BPM solver;
struct node{
    int h;
    string m,s;
    node(int h,string m,string s):h(h),m(m),s(s){}
};
bool ok(node a,node b){
    return abs(a.h-b.h)<=40&&a.m==b.m&&a.s!=b.s;
}
int R,C,N;
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        vector<node>a,b;
        for(int i=0;i<n;i++){
            int h;string m,s,sex;
            cin>>h>>sex>>m>>s;
            if(sex[0]=='M')a.push_back(node(h,m,s));
            else b.push_back(node(h,m,s));
        }
        int x=a.size(),y=b.size();
        solver.init(x,y);
        for(int i=0;i<x;i++)
            for(int j=0;j<y;j++)
            if(ok(a[i],b[j]))solver.G[i][j]=1;
        cout<<x+y-solver.solve()<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/luowentao/p/10352370.html

时间: 2024-10-31 10:31:22

训练指南 UVALive - 3415(最大点独立集)的相关文章

训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树)

layout: post title: 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树) author: "luowentaoaa" catalog: true mathjax: true tags: - Dijkstra - 最短路树 - 图论 - 训练指南 Warfare And Logistics UVALive - 4080 题意 ①先求任意两点间的最短路径累加和,其中不连通的边权为L ②删除任意一条边,求全局最短路径和的最大值 题解

训练指南 UVALive - 4043(二分图匹配 + KM算法)

layout: post title: 训练指南 UVALive - 4043(二分图匹配 + KM算法) author: "luowentaoaa" catalog: true mathjax: true tags: - 二分图匹配 - 图论 - 训练指南 Ants UVALive - 4043 题意 给你n个白点和n个黑点的平面坐标,要求用n条不相交的线连起来,每条线段连一个白点和黑点,每个点连一条线,也就是匹配.让你输出第i个白点所对应的黑点. 思路 二分图完美匹配问题.但是题目

训练指南 UVALive - 3126(DAG最小路径覆盖)

layout: post title: 训练指南 UVALive - 3126(DAG最小路径覆盖) author: "luowentaoaa" catalog: true mathjax: true tags: - 二分图 - 图论 - 训练指南 - 最小路径覆盖 Taxi Cab Scheme UVALive - 3126 题目大意:n个客人,从城市的不同位置出发,到达他们的目的地.已知每个人的出发时间hh:mm,出发地点(x1,y1)及目的地(x2,y2),要求使用最少的出租车接

训练指南DP阶段训练1

最近又忙又颓.............时间抓不紧....下学期开始就要准备考研了.......就2个月左右可以做自己喜欢的事了....争取把紫书和白书没做的,做过的..来一次完整的总结 训练指南上面的5个例题+后面15个习题是第一阶段 vjudge训练地址 http://vjudge.net/contest/139533#overview -------------------------------------------------------------------------------

训练指南 网络流题集

layout: post title: 训练指南 网络流题集 author: "luowentaoaa" catalog: true mathjax: true tags: - 网络流 - 图论 - 训练指南 A.UVA - 11248 (最大流,最小割) UVA - 11248 Frequency Hopping 题意 给定一个有向网络,每条边均有一个容量.问是否存在一个从点1到点N,流量为C的流.如果不存在,是否可以恰好修改一条弧的容量,使得存在这样的流. 思路 先求一遍最大流,如

计算几何-圆 模板 训练指南267

#include #include #include #include #include #include #include #include #include #include #define MM(a) memset(a,0,sizeof(a)) typedef long long ll; typedef unsigned long long ULL; const double eps = 1e-10; const int inf = 0x3f3f3f3f; using namespace

HDU--3829--Cat VS Dog【最大点独立集】

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3829 题意:动物园有n条狗,m头猫,p个小孩.每一个小孩有一个喜欢的动物和讨厌的动物,如今动物园要转移一些动物,假设一个小孩喜欢的动物在,不喜欢的动物不在,他就会happy,问动物最多能使几个小孩happy. 思路:一个比較明显的二分图.不能以猫狗为顶点,那样找到的是哪些动物会转移,以小孩为顶点,找出最大点独立集,有两种建图方式.一种是以小孩总数p为左右点集的顶点个数.假设小孩a喜欢的动物是小孩b不喜欢

POJ 1466 Girls and Boys【最大点独立集】

大意:最大点独立集 分析:最大点独立集 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 using namespace std; 6 7 const int maxn = 505; 8 9 int n; 10 int Link[maxn]; 11 int vis[maxn]; 12 vector<int> G[maxn

《训练指南》——6.13

困于时间缘故和考试缠身,笔者在先前关于<训练指南>的而第二章的数学基础的介绍先告一段落,开始对第一章简单的一些算法基础题目进行介绍. Uva11292: 你的王国里有一条n个头的恶龙,你希望雇一些其实把它杀死(即砍掉所有的头).村里有m个其实可以雇佣,一个能力值为x的其实可以砍掉恶龙一个半径不超过x的头,且需要支付x个金币.如何雇佣其实才能砍掉恶龙的所有头,且需要支付的金币最少?注意,一个其实只能看一个头(且只能被雇用一次). 分析:观察到题目给出支付最少的字眼,我们容易将其往动态规划或者贪心