zoukankan      html  css  js  c++  java
  • hdu 5093 Battle ships 匈牙利 很巧妙的建图思路

    //这题逼我把匈牙利学了 之前一直很勤快敲网络流 而且不以为耻反以为荣

    解:首先按行扫描编号,如果在同一块中(即可以相互攻击),那么将其标为相同的数组,对列也做同样的操作。

    然后扫描整张图,如果行编号为a的块与列编号为b的块有公共点,那么将二部图中A集合中a点与B集合中b点相连。最后求出来最大二分匹配数就是答案。

    (为什么这样做)首先很明显的,二部图中每一条边就对应原图中的一个点,因此,匹配数=边数=最多可放置的战舰数,另外二分图每个点只能匹配一次,对应到原题中就是每一块只能放置一个战舰.

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<queue>
      8 #include<vector>
      9 #include<map>
     10 #include<stack>
     11 #include<string>
     12 
     13 using namespace std;
     14 
     15 const int INF=2000000000;
     16 
     17 int T;
     18 int n,m,num_a,num_b;
     19 char c[51][51];
     20 int a[51][51];
     21 int b[51][51];
     22 bool adj[2501];
     23 int link[2501];
     24 int f[2501][2501];
     25 bool used[2501];
     26 
     27 bool work(int x){
     28     for (int i=1;i<=num_b;i++){
     29             if (f[x][i] && !adj[i]){
     30                     adj[i]=1;
     31                     if (!used[i] || work(link[i])){
     32                             link[i]=x;
     33                             used[i]=1;
     34                             return true;
     35                     }
     36             }
     37     }
     38     return false;
     39 }
     40 
     41 int main(){
     42     scanf("%d",&T);
     43     for (int cas=1;cas<=T;cas++){
     44             scanf("%d%d",&n,&m);
     45             for (int i=0;i<n;i++) scanf("%s",c[i]);
     46             memset(a,0,sizeof(a));
     47             memset(b,0,sizeof(b));
     48             int t=1;
     49             bool flag=0;
     50             for (int i=0;i<n;i++){
     51                     if (flag){
     52                             t++;
     53                             flag=false;
     54                     }
     55                     for (int j=0;j<m;j++){
     56                             if (c[i][j]=='*') {
     57                                     a[i][j]=t;
     58                                     flag=true;
     59                             }
     60                             if (flag && c[i][j]=='#'){
     61                                     flag=false;
     62                                     t++;
     63                             }
     64                     }
     65             }
     66             if (flag) t++;
     67             num_a=t-1;
     68             t=1;
     69             flag=0;
     70             for (int j=0;j<m;j++){
     71                     if (flag){
     72                             t++;
     73                             flag=false;
     74                     }
     75                     for (int i=0;i<n;i++){
     76                             if (c[i][j]=='*') {
     77                                     b[i][j]=t;
     78                                     flag=true;
     79                             }
     80                             if (flag && c[i][j]=='#'){
     81                                     flag=false;
     82                                     t++;
     83                             }
     84                     }
     85             }
     86             if (flag) t++;
     87             num_b=t-1;
     88             memset(used,0,sizeof(used));
     89             memset(f,0,sizeof(f));
     90             memset(link,0,sizeof(link));
     91             for (int i=0;i<n;i++){
     92                     for (int j=0;j<m;j++){
     93                             if (a[i][j]!=0 && b[i][j]!=0){
     94                                     f[a[i][j]][b[i][j]]=1;
     95                             }
     96                     }
     97             }
     98             int ans=0;
     99             for (int i=1;i<=num_a;i++){
    100                     memset(adj,0,sizeof(adj));
    101                     if (work(i)) ans++;
    102             }
    103             printf("%d
    ",ans);
    104     }
    105     return 0;
    106 }
    107 /*
    108 2
    109 4 4
    110 *ooo
    111 o###
    112 **#*
    113 ooo*
    114 4 4
    115 #***
    116 *#**
    117 **#*
    118 ooo#
    119 */
    View Code
  • 相关阅读:
    VS2015 出现 .NETSystem.Runtime.Remoting.RemotingException: TCP 错误
    C#学习笔记------参数
    C#简单工厂和抽象类的实例
    css基础1
    html中的div span和frameset框架标签
    关于C#委托的一些学习笔记
    html基础加强2
    HTML基础加强
    利用GDI+在Winfrom绘制验证码
    winfrom如何在listview中添加控件
  • 原文地址:https://www.cnblogs.com/baby-mouse/p/4654886.html
Copyright © 2011-2022 走看看