• POJ 1636


    题意:

    两个人数一样的监狱,有一些囚犯不能在一起,两个监狱要等数量(<m/2)交换一些囚犯,问最多可以交换多少个囚犯;

    根据条件可以画出一个二分图,接着可以由二分图得到的若干个连通分量。而当你选中一个囚犯的时候,因为约束条件,整个的连通分量都会受到牵连,

    即这个囚犯所在的连通分量的所有囚犯都要交换。设p[i],q[i]分别为这次选取的a,b监狱中所取囚犯个数;

    就可转化为背包问题;

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <string.h>
     4 using namespace std;
     5 const int M=202;
     6 bool rel[M][M],a[M],b[M],dp[M][M];
     7 int p[M],q[M];
     8 int n,m,r,aa,bb;
     9 void dfs(int i,int k){
    10     if(k){
    11         a[i]=1;
    12         aa++;
    13         for(int j=1;j<=m;j++){
    14             if(rel[i][j]&&!b[j]){
    15                 dfs(j,0);
    16             }
    17         }
    18     }
    19     else {
    20         b[i]=1;
    21         bb++;
    22         for(int j=1;j<=m;j++){
    23             if(rel[j][i]&&!a[j]){
    24                 dfs(j,1);
    25             }
    26         }
    27     }
    28 }
    29 int main(){
    30     int x,y;
    31     scanf("%d",&n);
    32     while(n--){
    33         int i;
    34         memset(rel,0,sizeof(rel));
    35         memset(dp,0,sizeof(dp));
    36         memset(a,0,sizeof(a));
    37         memset(b,0,sizeof(b));
    38         scanf("%d%d",&m,&r);
    39         for(i=0;i<r;i++){
    40             scanf("%d%d",&x,&y);
    41             rel[x][y]=1;
    42         }
    43         int t=0;
    44         for(i=1;i<=m;++i){
    45             if(!a[i]){
    46                 aa=bb=0;
    47                 dfs(i,1);
    48                 p[t]=aa;
    49                 q[t++]=bb;
    50             }
    51         }
    52         for(i=1;i<=m;++i){
    53             if(!b[i]){
    54                 aa=bb=0;
    55                 dfs(i,0);
    56                 p[t]=aa;
    57                 q[t++]=bb;
    58             }
    59         }
    60         dp[0][0]=1;
    61         for(i=0;i<t;++i){
    62             for(int j=m/2;j>=p[i];--j){
    63                 for(int k=m/2;k>=q[i];--k){
    64                     if(dp[j-p[i]][k-q[i]]){dp[j][k]=1;}
    65                 }
    66             }
    67         }
    68         for(i=m/2;i>=0;--i)if(dp[i][i]){break;}
    69         printf("%d
    ",i);
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    apache22与mod_mono
    设计模式之行为型模式
    jquery实现excel导出
    桥本分数式问题的C++算法
    [深入浅出iOS库]之图形库Core Plot
    HDU 1069 Monkey and Banana
    程序员咋学习
    JavaSocket通信(双向,有界面)
    BZOJ 3098(Hash Killer II生日攻击)
    [置顶] iPhone 5S及iWatch或将采用指纹验证技术
  • 原文地址:https://www.cnblogs.com/Mr-Xu-JH/p/4235677.html
Copyright © 2020-2023  润新知