zoukankan      html  css  js  c++  java
  • [USACO11NOV]牛的障碍Cow Steeplechase(匈牙利算法)

    洛谷传送门

    题目描述:

    给出N平行于坐标轴的线段,要你选出尽量多的线段使得这些线段两两没有交点(顶点也算),横的与横的,竖的与竖的线段之间保证没有交点,输出最多能选出多少条线段。

    因为横的与横的,竖的与竖的没有交点,所以直接把相交的线段相连,然后肯定是个二分图。

    选出多少个线段,就是求二分图的最大独立集,等于节点数(N) - 最大匹配数。

    由于线段的4个坐标太大 (X1_i, Y1_i) and (X2_i, Y2_i) (1 <= X1_i, Y1_i, X2_i, Y2_i <= 1,000,000,000),不能用二维矩阵来记录。

    又看到线段数量很少 (1 <= N <= 250),所以可以用结构体来存,然后通过两重循环判断线段是否相连。

    ——代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 
     5 using namespace std;
     6 
     7 int n, lh, ll, cnt, sum;
     8 int next[62501], to[62501], head[251], g[251];
     9 bool vis[251];
    10 struct node
    11 {
    12     int pos, minn, maxx;
    13 }h[10001], l[10001];
    14 
    15 void add(int x, int y)
    16 {
    17     to[cnt] = y;
    18     next[cnt] = head[x];
    19     head[x] = cnt++;
    20 }
    21 
    22 bool check(int i, int j)
    23 {
    24     if(h[i].pos < l[j].minn || h[i].pos > l[j].maxx) return 0;
    25     if(l[j].pos < h[i].minn || l[j].pos > h[i].maxx) return 0;
    26     return 1;
    27 }
    28 
    29 bool find(int u)
    30 {
    31     int i, v;
    32     for(i = head[u]; i != -1; i = next[i])
    33     {
    34         v = to[i];
    35         if(!vis[v])
    36         {
    37             vis[v] = 1;
    38             if(!g[v] || find(g[v]))
    39             {
    40                 g[v] = u;
    41                 return 1;
    42             }
    43         }
    44     }
    45     return 0;
    46 }
    47 
    48 int main()
    49 {
    50     int i, j, x1, y1, x2, y2;
    51     scanf("%d", &n);
    52     memset(head, -1, sizeof(head));
    53     for(i = 1; i <= n; i++)
    54     {
    55         scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
    56         if(x1 == x2)
    57         {
    58             ++lh;
    59             h[lh].pos = x1;
    60             h[lh].minn = min(y1, y2);
    61             h[lh].maxx = max(y1, y2);
    62         }
    63         else if(y1 == y2)
    64         {
    65             ++ll;
    66             l[ll].pos = y1;
    67             l[ll].minn = min(x1, x2);
    68             l[ll].maxx = max(x1, x2);
    69         }
    70     }
    71     for(i = 1; i <= lh; i++)
    72      for(j = 1; j <= ll; j++)
    73       if(check(i, j))
    74        add(i, j);
    75     for(i = 1; i <= lh; i++)
    76     {
    77         memset(vis, 0, sizeof(vis));
    78         if(find(i)) sum++;
    79     }
    80     printf("%d", n - sum);
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    Demo学习: DownloadDemo
    Demo学习: FileUpload
    Demo学习: Dialogs Anonymous Callback
    Demo学习: Cookies Demo
    Demo学习: CustomException
    Demo学习: Collapsible Panels
    Demo学习: ColumnSort
    Demo学习: ClientInfo
    Demo学习: Closable Tabs
    Demo学习: ClientEvents
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6702200.html
Copyright © 2011-2022 走看看