POJ1636

问题重述:

两个监狱中各有m个囚犯,欲对这两个监狱中的囚犯进行等数量的交换。已知某些囚犯不能关押在同一个监狱,求解可以交换人数的最大值k (k < m/2)。

分析:

假设监狱1中的囚犯a与监狱2中的囚犯b不能共存。那么假如对a进行交换,也必须对b进行交换。因此,根据互斥关系建立的连通集两边的成员必须同时进行交换。

求解步骤:

1)  根据已知的互斥关系,采用并查集建立连通集,分别记录每个连通集在两个监狱中的成员数目,记为v1, v2。

2)  采用动态规划算法,用布尔变量dp[i][j]表示监狱1中i个囚犯与监狱2中的j个囚犯进行交换的可行性。则有dp[i][j] = dp[i – v1[k]][j – v2[k]]

3)  满足dp[i][i] = 1, i < m/2的i的最大值即所求的解。

 //Memory: 580K        Time: 63MS
 #include <iostream>
 #include <cstring>
 #include <cstdio>

 using namespace std;

 ;
 int m, r;
 bool g[maxn][maxn];
 int f[maxn];
 int nl[maxn];
 int nr[maxn];
 bool vis[maxn];
 int v1[maxn], v2[maxn];
 int cnt;
 bool dp[maxn][maxn];

 void makeset()
 {
     memset(f, , sizeof(f));
     memset(nl, , sizeof(nl));
     memset(nr, , sizeof(nr));
     ; i <=  * m; i++)
         f[i] = i;
     ; i <= m; i++) {
         nl[i] = ;
         nr[i] = ;
     }
      + m; i <= m * ; i++) {
         nr[i] = ;
         nl[i] = ;
     }
 }

 int find(int a) {
     if (f[a] == a) return a;
     f[a] = find(f[a]);
     return f[a];
 }

 void uni(int a, int b) {
     int sa = find(a);
     int sb = find(b);
     if (sa != sb) {
         f[sa] = sb;
         nl[sb] += nl[sa];
         nr[sb] += nr[sa];
     }
 }

 void init()
 {
     makeset();
     ; i <= m; i++) {
         ; j <= m * ; j++) if (g[i][j]) {
             uni(i, j);
         }
     }
     cnt = ;
     ; i <= m * ; i++) {
         int s = find(i);
         if (s == i) {
             v1[cnt] = nl[s];
             v2[cnt++] = nr[s];
         }
     }
 }

 int main()
 {
     int cas;
     cin >> cas;
     while (cas--) {
         memset(g, , sizeof(g));
         scanf("%d%d", &m, &r);
         int a, b;
         ; i < r; i++) {
             scanf("%d%d", &a, &b);
             g[a][b + m] = ;
         }
         init();

         memset(dp, , sizeof(dp));
         dp[][] = ;
         ; i < cnt; i++) {
             ; j >= ; j--)  ////此处必须进行倒序循环:每次循环的dp都由上一轮循环后序号较小的dp确定,倒序循环避免提前更新序号较小的dp
                 ; k >= ; k--) {  //同上
                      && k + v2[i] <= m/)
                         dp[j + v1[i]][k + v2[i]] = ;
                 }
         }

         ; i >= ; i--) {
             if (dp[i][i]) {
                 cout << i <<endl;
                 break;
             }
         }
     }
     ;
 }

POJ1636 动态规划+并查集的更多相关文章

  1. POJ1417 True Liars 并查集 动态规划 (种类并查集)

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ1417 题意概括 有一群人,p1个好人,p2个坏人. 他们说了n句话.(p1+p2<=600,n ...

  2. 【2019.10.7 CCF-CSP-2019模拟赛 T3】未知的数组(unknown)(并查集+动态规划)

    预处理 考虑模数\(10\)是合数不好做,所以我们可以用一个常用套路: \(\prod_{i=l}^ra_i\equiv x(mod\ 10)\)的方案数等于\(\prod_{i=l}^ra_i\eq ...

  3. [POJ2054]Color a Tree (并查集+贪心)

    POJ终于修好啦 题意 和UVA1205是同一题,在洛谷上是紫题 有一棵树,需要给其所有节点染色,每个点染色所需的时间是一样的都是11.给每个点染色,还有一个开销“当前时间×ci×ci”,cici是每 ...

  4. POJ-1456 Supermarket(贪心,并查集优化)

    Supermarket Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10725 Accepted: 4688 Descript ...

  5. POJ 1417 - True Liars - [带权并查集+DP]

    题目链接:http://poj.org/problem?id=1417 Time Limit: 1000MS Memory Limit: 10000K Description After having ...

  6. POJ1417 True Liars —— 并查集 + DP

    题目链接:http://poj.org/problem?id=1417 True Liars Time Limit: 1000MS   Memory Limit: 10000K Total Submi ...

  7. leetcode 76 dp& 强连通分量&并查集经典操作

    800. Similar RGB Color class Solution { int getn(int k){ return (k+8)/17; } string strd(int k){ char ...

  8. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  9. 关押罪犯 and 食物链(并查集)

    题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...

随机推荐

  1. MySQL查询指定时间的数据

    user_event :用户事件表 create_time :表中存储时间的字段 #获取当月数据 SELECT * FROM user_event WHERE DATE_FORMAT(create_t ...

  2. Swift类和结构体定义-备

    Swift中的类和结构体定义的语法是非常相似的.类使用class关键词定义类,使用struct关键词定义结构体,它们的语法格式如下: class 类名 { 定义类的成员 } struct 结构体名 { ...

  3. Light OJ 1314 Names for Babies

    http://www.lightoj.com/volume_showproblem.php?problem=1314 题意:给定一个串和p,q,求长度在p到q之间的子串有几种 思路:后缀数组,对于每个 ...

  4. 关于API的设计和需求抽象

    一,先来谈抽象吧,因为抽象跟后面的API的设计是息息相关的 有句话说的好(不知道谁说的了):计算机科学中的任何问题都可以抽象出一个中间层就解决了. 抽象是指在思维中对同类事物去除其现象的.次要的方面, ...

  5. Leetcode:LRUCache四个版本实现

    题目 Design and implement a data structure for Least Recently Used (LRU) cache. It should support the ...

  6. Windows Azure 存储管理器 (2014)

     Windows Azure存储用户经常希望能够在"管理器"中查看他们的数据,管理器指的是一款可用于显示存储帐户数据的工具.我们之前提供了我们所知的存储管理器列表.在本文中,我 ...

  7. Delphi 把字符串读到流中的操作。

    var FReQuestM := TMemoryStream FReQuestM.Write(PChar(FcVoucherXML)^, Length(FcVoucherXML)); 这样就读到流中了 ...

  8. poj1305:概念水题

    了解一下毕达哥拉斯三元组概念= = 暴力求出所有的本源三元组即可 代码: #include <iostream> #include <stdio.h> #include< ...

  9. MVC 控制器详解

    Controller: Controllers 文件夹包含负责处理用户输入和响应的控制器类. MVC 要求所有控制器的名称必须以 "Controller" 结尾. 控制器的职责: ...

  10. pyqt小例子 音乐盒

    源代码1: # -*- coding: utf-8 -*- import sys,time,os import ctypes from PyQt4 import QtCore, QtGui,Qt fr ...