zoukankan      html  css  js  c++  java
  • POJ 3020(最小路径覆盖+拆点)

    题意:一个矩形中,有N个城市’*’,现在这n个城市都要覆盖无线,若放置一个基站,那么它至多可以覆盖相邻的两个城市。
    问至少放置多少个基站才能使得所有的城市都覆盖无线?

    思路:每个城市才是要构造的二分图的顶点,先把每个*用数字1-n标记起来,然后构造无向二分图,无向二分图的构造需要拆点,即1<—>2之间的双向边要拆成两条有向边,1—>2',2—>1'。且点集(1,2)(2',1')分别属于二分图的两个顶点集V1,V2。再跑一遍匈牙利,结果就是 “顶点数—最大匹配数/2”。

    二分图的一点小知识:

    最大匹配: 图中包含边数最多的匹配称为图的最大匹配。 
    完美匹配: 如果所有点都在匹配边上,称这个最大匹配是完美匹配。
    最小覆盖: 最小覆盖要求用最少的点(X集合或Y集合的都行)让每条边都至少和其中一个点关联。可以证明:最少的点(即覆盖数)=最大匹配数
    最小路径覆盖:
    用尽量少的不相交简单路径覆盖有向无环图G的所有结点。解决此类问题可以建立一个二分图模型。把所有顶点i拆成两个:X结点集中的i和Y结点集中的i',如果有边i->j,则在二分图中引入边i->j',设二分图最大匹配为m,则结果就是n-m。
    最大独立集问题:
    在N个点的图G中选出m个点,使这m个点两两之间没有边.求m最大值.
    如果图G满足二分图条件,则可以用二分图匹配来做.最大独立集点数 = N - 最大匹配数。

      1 #include <iostream>
      2 #include <queue>
      3 #include <stack>
      4 #include <cstdio>
      5 #include <vector>
      6 #include <map>
      7 #include <set>
      8 #include <bitset>
      9 #include <algorithm>
     10 #include <cmath>
     11 #include <cstring>
     12 #include <cstdlib>
     13 #include <string>
     14 #include <sstream>
     15 #include <time.h>
     16 #define x first
     17 #define y second
     18 #define pb push_back
     19 #define mp make_pair
     20 #define lson l,m,rt*2
     21 #define rson m+1,r,rt*2+1
     22 #define mt(A,B) memset(A,B,sizeof(A))
     23 using namespace std;
     24 typedef long long LL;
     25 //const double PI = acos(-1);
     26 const int N=4e2+10;
     27 const LL mod=1e9+7;
     28 const int inf = 0x3f3f3f3f;
     29 const LL INF=0x3f3f3f3f3f3f3f3fLL;
     30 int un,vn,n;
     31 int g[N][N];
     32 int linker[N];
     33 bool used[N];
     34 char s[N][N];
     35 int vis[N][N];
     36 bool dfs(int u)
     37 {
     38     for(int v=1;v<=vn;v++)
     39     {
     40         if(g[u][v]&&!used[v])
     41         {
     42             used[v]=true;
     43             if(linker[v]==-1||dfs(linker[v]))
     44             {
     45                 linker[v]=u;
     46                 return true;
     47             }
     48         }
     49     }
     50     return false;
     51 }
     52 int hungary()
     53 {
     54     int res=0;
     55     mt(linker,-1);
     56     for(int i=1;i<=un;i++)
     57     {
     58         mt(used,false);
     59         if(dfs(i))res++;
     60     }
     61     return res;
     62 }
     63 int main()
     64 {
     65 #ifdef Local
     66     freopen("data.txt","r",stdin);
     67 #endif
     68     //ios::sync_with_stdio(false);
     69    // cin.tie(0);
     70     int T,k;
     71     cin>>T;
     72     while(T--)
     73     {
     74         k=1;
     75         mt(g,0);
     76         mt(vis,0);
     77         cin>>un>>vn;
     78         //cout<<un<<" "<<vn<<endl;
     79         for(int i=0;i<un;i++)
     80         {
     81             scanf("%s",s[i]);
     82         }
     83         for(int i=0;i<un;i++)
     84         {
     85             for(int j=0;j<vn;j++)
     86             {
     87                 if(s[i][j]=='*')
     88                 {
     89                     vis[i][j]=k;
     90                     k++;
     91                 }
     92             }
     93         }
     94         for(int i=0;i<un;i++)
     95         {
     96             for(int j=0;j<vn;j++)
     97             {
     98                 if(vis[i][j])
     99                 {
    100                     if(i+1<un&&vis[i+1][j])
    101                     {
    102                         g[vis[i][j]][vis[i+1][j]]=1;
    103                         g[vis[i+1][j]][vis[i][j]]=1;
    104                     }
    105                     if(i-1>=0&&vis[i-1][j])
    106                     {
    107                         g[vis[i][j]][vis[i-1][j]]=1;
    108                         g[vis[i-1][j]][vis[i][j]]=1;
    109                     }
    110                     if(j+1<vn&&vis[i][j+1])
    111                     {
    112                         g[vis[i][j]][vis[i][j+1]]=1;
    113                         g[vis[i][j+1]][vis[i][j]]=1;
    114                     }
    115                     if(j-1>=0&&vis[i][j-1])
    116                     {
    117                         g[vis[i][j]][vis[i][j-1]]=1;
    118                         g[vis[i][j-1]][vis[i][j]]=1;
    119                     }
    120                 }
    121             }
    122         }
    123         un=vn=k;
    124         cout<<k-hungary()/2-1<<endl;
    125     }
    126 #ifdef Local
    127     cerr << "time: " << (LL) clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    128 #endif
    129 }
    View Code
  • 相关阅读:
    gitlab文件夹的权限不要随便给777
    记python版本管理--pyenv
    centos7上基于kubernetes的docker集群管理
    centos下修改docker连接docker_host默认方式为tls方式
    微信公众帐号开发之一(java)
    java抓取12306火车余票信息
    对Word2Vec的理解
    软件工程课程助教总结
    2017面向对象程序设计(Java)第十七周助教工作总结
    2017面向对象程序设计(Java)第十三周助教工作总结
  • 原文地址:https://www.cnblogs.com/27sx/p/6637003.html
Copyright © 2011-2022 走看看