• HDOJ1281解题报告【棋盘向二分图的转化】


    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1281

    题目概述:

      中文题……简单说明下重要点是指这个点必须放一个車的点。

    大致思路:

      二分图匹配的题目,将每一行1-n作为S集合,每一列1-m作为T集合,如果有一个点(x,y)就将S集合中的x与T集合中的y连一条边代表这个方格。

      求重要点就每次删除二分图中的一条边,看最大匹配有没有发生变化,有即为重要点。

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <vector>
     6 #include <ctime>
     7 #include <map>
     8 #include <queue>
     9 #include <cstring>
    10 #include <algorithm>
    11 using namespace std;
    12 
    13 #define sacnf scanf
    14 #define scnaf scanf
    15 #define maxn 310
    16 #define maxm 26
    17 #define inf 1061109567
    18 #define Eps 0.00001
    19 const double PI=acos(-1.0);
    20 #define mod 7
    21 #define MAXNUM 10000
    22 void Swap(int &a,int &b) {int t=a;a=b;b=t;}
    23 double Abs(double x) {return (x<0)?-x:x;}
    24 typedef long long ll;
    25 typedef unsigned int uint;
    26 
    27 int n,m,k;
    28 int x[maxn],y[maxn];
    29 int G[maxn][maxn];
    30 int vis[maxn],l[maxn];
    31 
    32 bool dfs(int u)
    33 {
    34     for(int i=1;i<=n+m;i++)
    35     {
    36         if(!G[u][i]) continue;
    37         if(!vis[i])
    38         {
    39             vis[i]=1;
    40             if(l[i]==-1||dfs(l[i]))
    41             {
    42                 l[i]=u;return true;
    43             }
    44         }
    45     }
    46     return false;
    47 }
    48 
    49 int hungary()
    50 {
    51     int cnt=0;
    52     memset(l,-1,sizeof(l));
    53     for(int i=1;i<=n;i++)
    54     {
    55         memset(vis,0,sizeof(vis));
    56         if(dfs(i)) cnt++;
    57     }
    58     return cnt;
    59 }
    60 
    61 int main()
    62 {
    63     //freopen("data.in","r",stdin);
    64     //freopen("data.out","w",stdout);
    65     //clock_t st=clock();
    66     int kase=0;
    67     while(~scnaf("%d%d%d",&n,&m,&k))
    68     {
    69         kase++;
    70         for(int i=1;i<=n;i++)
    71         {
    72             for(int j=1;j<=n+m;j++) G[i][j]=0;
    73         }
    74         for(int i=1;i<=k;i++)
    75         {
    76             scanf("%d%d",&x[i],&y[i]);
    77             G[x[i]][n+y[i]]=G[n+y[i]][x[i]]=1;
    78         }
    79         int ans1=hungary(),ans2=0;
    80         for(int i=1;i<=k;i++)
    81         {
    82             G[x[i]][n+y[i]]=G[n+y[i]][x[i]]=0;
    83             if(hungary()!=ans1) ans2++;
    84             G[x[i]][n+y[i]]=G[n+y[i]][x[i]]=1;
    85         }
    86         printf("Board %d have %d important blanks for %d chessmen.
    ",kase,ans2,ans1);
    87     }
    88     //clock_t ed=clock();
    89     //printf("
    
    Time Used : %.5lf Ms.
    ",(double)(ed-st)/CLOCKS_PER_SEC);
    90     return 0;
    91 }
  • 相关阅读:
    【读书笔记】深入理解计算机系统
    快速排序
    列表查找的两种方法
    冒泡排序、选择排序、插入排序
    堆排序
    supervisor进程管理
    redis-主从复制
    redis-淘汰策略
    URI和URL
    python爬虫之xpath的基本使用
  • 原文地址:https://www.cnblogs.com/CtrlKismet/p/6511127.html
Copyright © 2020-2023  润新知