• poj 1636 Prison rearrangement


    Prison rearrangement
     
    Time Limit: 3000MS   Memory Limit: 10000K
    Total Submissions: 2158   Accepted: 971

    Description

    In order to lower the risk of riots and escape attempts, the boards of two nearby prisons of equal prisoner capacity, have decided to rearrange their prisoners among themselves. They want to exchange half of the prisoners of one prison, for half of the prisoners of the other. However, from the archived information of the prisoners' crime history, they know that some pairs of prisoners are dangerous to keep in the same prison, and that is why they are separated today, i.e. for every such pair of prisoners, one prisoners serves time in the first prison, and the other in the second one. The boards agree on the importance of keeping these pairs split between the prisons, which makes their rearrangement task a bit tricky. In fact, they soon find out that sometimes it is impossible to fulfil their wish of swapping half of the prisoners. Whenever this is the case, they have to settle for exchanging as close to one half of the prisoners as possible.

    Input

    On the first line of the input is a single positive integer n, telling the number of test scenarios to follow. Each scenario begins with a line containing two non-negative integers m and r, 1 < m < 200 being the number of prisoners in each of the two prisons, and r the number of dangerous pairs among the prisoners. Then follow r lines each containing a pair xi yi of integers in the range 1 to m,which means that prisoner xi of the first prison must not be placed in the same prison as prisoner yi of the second prison.

    Output

    For each test scenario, output one line containing the largest integer k <= m/2 , such that it is possible to exchange k prisoners of the first prison for k prisoners of the second prison without getting two prisoners of any dangerous pair in the same prison.

    Sample Input

    3
    101 0
    3 3
    1 2
    1 3
    1 1
    8 12
    1 1
    1 2
    1 3
    1 4
    2 5
    3 5
    4 5
    5 5
    6 6
    7 6
    8 7
    8 8

    Sample Output

    50
    0
    3
    原文地址
    题目意思:两个监狱,各有n个犯人,每个两个监狱之间一些犯人之间有一定的关系,对于有关系的犯人不能放在同一个监狱,原状态肯定是满足的,
    因为存在这种关系的不存在同一个监狱的。求最大交换次数使得条件依然满足,并且交换次数不能超过n/2。

    后记:我们两队的比赛题,琨哥说题目很水,我信了,这能水,唉,高估我们能力了,主要是用到 dfs + o1 背包问题,但是的确很难想到,我还想着用并查集呢,不会,参考了下别人的代码;
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 using namespace std;
      5 const int SIZE = 205;
      6 int m;
      7 int r;
      8 //map[i][j]表示i和j是否会冲突
      9 int map[SIZE][SIZE];
     10 //A组里的人数
     11 int aSize;
     12 //b组里的人数
     13 int bSize;
     14 //dp[i][j] 表示用A组的i个人换B组的j个人是否可行
     15 bool dp[SIZE][SIZE];
     16 //visited[0][i] 表示用A组中的点i是否被访问过
     17 //visited[1][i] 表示用B组中的点i是否被访问过
     18 bool visited[2][SIZE];
     19 void Init()
     20 {
     21     memset( map, 0, sizeof(map) );
     22     memset( visited, 0, sizeof(visited) );
     23     memset( dp, 0, sizeof(dp) );
     24 }
     25 void Input()
     26 {
     27     cin >> m >> r;
     28     for( int i=0; i<r; i++ )
     29     {
     30         int a, b;
     31         cin >> a >> b;
     32         map[a][b] = 1;
     33     }
     34 }
     35 //side=0  表示当前正在搜索A组
     36 //side=1  表示当前正在搜索B组
     37 //id 表示当前正在搜索的编号
     38 void DFS( int side, int id )
     39 {
     40     visited[side][id] = true;
     41     //如果当前搜索的是A组
     42     if( side == 0 )
     43     {
     44         //记录A组中的元素个数
     45         aSize++;
     46         for( int i=1; i<=m; i++ )
     47         {
     48             //搜索的是B组中对应的点
     49             if( map[id][i] && !visited[1][i] )//看一组的 id ,是否有和二组的 i ,相连的不,并且二组的没有被标记;
     50             {
     51                 DFS( 1, i ); //搜寻一组中是否有与二组相连的数;
     52             }
     53         }
     54     }
     55     else
     56     {
     57         bSize++;
     58         for( int j=1; j<=m; j++ )
     59         {
     60             if( map[j][id] && !visited[0][j] )
     61             {
     62                 DFS( 0, j );
     63             }
     64         }
     65     }
     66 }
     67 //利用二维背包计算
     68 void Knapsack()
     69 {
     70     dp[0][0] = true;
     71     for( int x=m/2; x>=aSize-1; x-- )
     72     {
     73         for( int y=m/2; y>=bSize-1; y-- )
     74         {
     75             if( dp[x][y] || dp[x - aSize][y - bSize] )
     76             {
     77                // printf("%d %d
    ",x,y);
     78                 dp[x][y] = true;
     79             }
     80         }
     81     }
     82 }
     83 void Output()
     84 {
     85     for( int i=m/2; i>=0; i-- )
     86     {
     87         if( dp[i][i] )                         // dp[i][i]; 表示各方都拿出来 i 个人,进行交换;
     88         {
     89             cout << i << endl;
     90             break;
     91         }
     92     }
     93 }
     94 int main()
     95 {
     96     int caseNum;
     97     cin >> caseNum;
     98     while( caseNum-- )
     99     {
    100         Init();
    101         Input();
    102         for( int i=1; i<=m; i++ )
    103         {
    104             //跳过已经处理过的节点
    105             if( visited[0][i] ) continue;
    106             //计算A、B中的人数
    107             aSize = 0;
    108             bSize = 0;
    109             DFS( 0, i );    //  搜索一次,就出现两组不相容的团体;
    110             //利用二维背包计算
    111             Knapsack();
    112         }
    113         for( int i=1; i<=m; i++ )
    114         {
    115             if( visited[1][i] ) continue;
    116             aSize = 0;
    117             bSize = 0;
    118             DFS( 1, i );
    119             Knapsack();
    120         }
    121         Output();
    122     }
    123     return 0;
    124 }
  • 相关阅读:
    Django项目引入NPM和gulp管理前端资源
    Django实现统一包装接口返回值数据格式
    即学即会 Serverless | 如何解决 Serverless 应用开发部署的难题?
    足不出户,搞定交付——独家交付秘籍(第二回)
    如何使用阿里云容器服务保障容器的内存资源质量
    恭喜我的同事丁宇入选年度 IT 领军人物
    基于 KubeVela 的机器学习实践
    基于 KubeVela 的机器学习实践
    OpenKruise v1.1:功能增强与上游对齐,大规模场景性能优化
    云原生时代如何用 Prometheus 实现性能压测可观测Metrics 篇
  • 原文地址:https://www.cnblogs.com/lovychen/p/3685079.html
Copyright © 2020-2023  润新知