• Asteroids POJ


    题意: 给出一个N*N的地图N   地图里面有K个障碍     你每次可以选择一条直线 消除这条直线上的所有障碍  (直线只能和列和行平行) 

    问最少要消除几次

    题解: 如果(x,y)上有一个障碍 则把X加入点集 V1 、Y加入点集V2   并且X Y连一条边  这样构成一个新图

    如果选择 V1中的点 X 那么就相当于消去 (X,y)中的所有Y    要找使最小点覆盖 那就是跑一遍 匈牙利就行了 详细证明见二分图最小点覆盖König定理

    其中 x y需要连单向边 不然会造成混乱 因为x=1 y=1是不同的含义

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=1000;
     6 int n,k;
     7 int mp[maxn][maxn];
     8 int girl[maxn];
     9 int used[maxn];
    10 bool find(int x){
    11     int i,j;
    12     for(j=1;j<=n;j++){
    13         if(mp[x][j]==1&&used[j]==0){
    14             used[j]=1;
    15             if(girl[j]==0||find(girl[j])){
    16                 girl[j]=x;
    17                 return 1;
    18             }
    19         }
    20     }
    21     return 0;
    22 }
    23 int main(){
    24     cin>>n>>k;
    25     for(int i=1;i<=k;i++){
    26         int a,b;
    27         scanf("%d%d",&a,&b);//建边
    28         mp[a][b]=1;
    29     }
    30     int sum=0;
    31     for(int i=1;i<=n;i++){
    32         memset(used,0,sizeof(used));//每次要初始化 因为used是用于判断之前有没有用过 什么叫之前有没用用过  比如进入3的递归,used[2]=1,3 和2匹配  2已经在之前已经有归属了  现在要进行拆边 find(girl(j))  此时假设girl(j)=5,5就不能和2匹配了,因为现在进行拆边操作时逻辑上已经认定 上层递归的used[2]=1 已经用了2
    33         if(find(i))sum++;
    34     }
    35 cout<<sum<<endl;
    36     return 0;
    37 }
  • 相关阅读:
    XAF 如何在工具栏显示多参数
    XAF Study Recources
    常用工具
    Linux下Kill函数用法
    ipv6相关转换
    宣布回归
    微软夏令营
    APEX SDK阅后感
    寻求offer,开始记录我的征程
    衣服模拟结果
  • 原文地址:https://www.cnblogs.com/ttttttttrx/p/10012352.html
Copyright © 2020-2023  润新知