zoukankan      html  css  js  c++  java
  • poj

    http://poj.org/problem?id=3041

    在n*n的网格中有K颗小行星,小行星i的位置是(Ri,Ci),现在有一个强有力的武器能够用一发光速将一整行或一整列的小行星轰为灰烬,想要利用这个武器摧毁所有的小行星最少需要几发光束.

    主要是构图,将每一行当成一个点,构成集合1,每一列也当成一个点,构成集合2,每一个障碍物的位置坐标将集合1和集合2的点连接起来,也就是将每一个障碍物作为连接节点的边,这样可以得出本题是一个最小点覆盖的问题==二分图的最大匹配.

    就可以通过匈牙利算法求解。

    邻接表实现 0ms.

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 class edge{
     6 public:
     7     int v,nex;
     8 };
     9 edge e[10001];
    10 int n,m,k,head[10001];
    11 int link[501];
    12 bool vis[501];
    13 
    14 void init()
    15 {
    16     k=0;
    17     memset(head,0,sizeof(head));
    18 }
    19 void addedge(int b,int a)
    20 {//向图中加边的算法,注意加上的是有向边//b为a的后续节点既是a---->b
    21     e[k].v=a;
    22     e[k].nex=head[b];
    23     head[b]=k;k++;
    24 }
    25 bool dfs(int u){
    26     for(int i = head[u]; i != 0; i = e[i].nex){
    27         int v = e[i].v;
    28         if(!vis[v]){
    29             vis[v] = true;
    30             if(link[v] == -1 || dfs(link[v])){
    31                 link[v] = u;
    32                 return true;
    33             }
    34         }
    35     }
    36     return false;
    37 }
    38 int main()
    39 {
    40     int u,v;
    41     scanf("%d%d",&n,&m);
    42     init();
    43     for(int i=0;i<m;i++)
    44     {
    45         scanf("%d%d",&u,&v);
    46         addedge(v-1,u-1);
    47     }
    48     int ans=0;
    49     memset(link,-1,sizeof(link));
    50     for(int i = 0; i < n; i ++){
    51         memset(vis,0,sizeof(vis));
    52         if(dfs(i)) ans++;
    53     }
    54     printf("%d
    ", ans);
    55     return 0;
    56 }

    邻接矩阵:

     1 #include <cstdio>
     2 #include <cstring>
     3 const int MAXN=501;
     4 int uN,vN;  //u,v数目
     5 int g[MAXN][MAXN];//编号是0~n-1的
     6 int linker[MAXN];
     7 bool used[MAXN];
     8 bool dfs(int u)
     9 {
    10     int v;
    11     for(v=0;v<uN;v++)
    12         if(g[u][v]&&!used[v])
    13         {
    14             used[v]=true;
    15             if(linker[v]==-1||dfs(linker[v]))
    16             {
    17                 linker[v]=u;
    18                 return true;
    19             }
    20         }
    21     return false;
    22 }
    23 int hungary()
    24 {
    25     int res=0;
    26     int u;
    27     memset(linker,-1,sizeof(linker));
    28     for(u=0;u<uN;u++)
    29     {
    30         memset(used,0,sizeof(used));
    31         if(dfs(u))  res++;
    32     }
    33     return res;
    34 }
    35 
    36 int main()
    37 {
    38     int u,v;
    39     scanf("%d%d",&uN,&vN);
    40     memset(g,0,sizeof(g));
    41     while(vN--)
    42     {
    43         scanf("%d%d",&u,&v);
    44         g[u-1][v-1]=1;
    45     }
    46     printf("%d
    ",hungary());
    47     return 0;
    48 
    49 }
  • 相关阅读:
    CATransition
    OC中只有重写没有重载
    OC内存管理
    NSNotification
    关于一个小应用软件的思考
    tableView主从表在storyboard连线是 Selcetion Segue和Accessory Action的区别
    关于ios8模拟器不能输入中文问题以及软键盘不弹出问题
    UINavigation Bar中使用UIcollectionView,在UIcollectionView的顶端和低端出现空白的问题
    升级到Xcode6.2后 免证书真机调试出错的问题
    让UITableView 的 headerView跟随 cell一起滚动,tableHeaderView
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4564405.html
Copyright © 2011-2022 走看看