zoukankan      html  css  js  c++  java
  • 【noip模拟】最小点覆盖

    Time Limit: 1000ms      Memory Limit: 128MB  

    Description

    最小点覆盖是指在二分图中,用最小的点集覆盖所有的边。当然,一个二分图的最小点覆盖可能有很多种。

    现在给定一个二分图,请你把图中的点分成三个集合:

    如果在任何一种最小点覆盖中都不包含这个点,则认为该点属于N集合。

    如果在任何一种最小点覆盖中都包含这个点,则认为该点属于A集合。

    如果一个点既不属于N集合,又不属于A集合,则认为该点属于E集合。

     

    Input

    第一行包含三个整数n, m, k,分别表示二分图A侧点的数量,二分图B侧点的数量,边的数量。

    接下来k行,每行两个整数i, j,分别表示二分图A侧第i号点与二分图B侧第j号点有连边。

    数据保证无重边。

     

    Output

    第一行输出一个长度为n的字符串,其中第i个字符表示二分图A侧第i个点所属的集合。

    第二行输出一个长度为m的字符串,其中第i个字符表示二分图B侧第i个点所属的集合。

    Sample Input

    11 9 22

    1 1

    1 2

    1 3

    1 8

    1 9

    2 1

    2 3

    3 2

    3 4

    4 3

    4 5

    5 2

    5 4

    5 6

    6 6

    6 7

    7 5

    7 7

    8 7

    9 7

    10 7

    11 7

    Sample Output

    AEEEEEENNNN

    EEEEEEANN

    HINT

    对于10%的数据,$1≤n,m≤5$

    对于40%的数据,$1≤n,m≤100$

    对于100%的数据,$1≤n,m≤1000, 0≤k≤n∗m$

    [吐槽]

      场上?嗯。。大眼瞪小眼qwq

    [题解]

      嗯首先码一下最小点覆盖的相关知识

      König定理

      一个二分图中最大的匹配数=该图中最小点覆盖数

      (写得比较长所以就拎出来啦不然对不起自己就是这样哈哈)

      http://www.cnblogs.com/yoyoball/p/7632871.html

      从链接回到这道题

      铺垫什么的。。好像略微有点多不过。。

      嗯不管了

      然后我们就可以得出一个结论:

      如果一个点没有任何一条匹配边连到,那么这个点肯定不在最小点覆盖中

      从而与它相连的点必定要在最小点覆盖中(不然这两点之间的连边就不能覆盖到了)

      而对于一个必定在最小点覆盖中的点,与它的匹配点必定不在最小点覆盖中

      然后就这样顺着遍历同时标记就好啦

      对于那些没有被标记到的点,肯定就是属于E的啦

      好的于是在漫长的铺垫之后这题终于解决啦ovo

      (果然把最小点覆盖的东西拎出来之后清爽了很多哈哈哈)

    [一些细节]

      首先。。要用long long

      其次。。注意边数

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const int MAXN=1010*2;
     6 struct xxx
     7 {
     8     int y,next;
     9 }a[1010*1010*2];
    10 char mark[MAXN];
    11 bool vis[MAXN];
    12 int h[MAXN],match[MAXN];
    13 int n,m,tot,k,ans;
    14 int add(int x,int y);
    15 bool dfs(int x);
    16 int solve();
    17 int work(int x,int op);
    18 
    19 int main()
    20 {
    21 //    freopen("a.in","r",stdin);
    22 
    23     int x,y;
    24     scanf("%d%d%d",&n,&m,&k);
    25     memset(h,-1,sizeof(h));
    26     tot=0;
    27     for (int i=1;i<=k;++i)
    28     {
    29         scanf("%d%d",&x,&y);
    30         add(x,n+y); add(n+y,x);
    31     }
    32     memset(match,0,sizeof(match));
    33     for (int i=1;i<=n+m;++i) mark[i]='E';
    34     for (int i=1;i<=n;++i)
    35         if (!match[i])
    36         {
    37             memset(vis,false,sizeof(vis));
    38             if (dfs(i)) ++ans;
    39         }
    40 //    for (int i=1;i<=n;++i) printf("%d ",match[i]-n);
    41     solve();
    42     for (int i=1;i<=n;++i) printf("%c",mark[i]);
    43     printf("
    ");
    44     for (int i=n+1;i<=n+m;++i) printf("%c",mark[i]);
    45 }
    46 
    47 int add(int x,int y)
    48 {
    49     a[++tot].y=y; a[tot].next=h[x]; h[x]=tot;
    50 }
    51 
    52 bool dfs(int x)
    53 {
    54     int u;
    55     for (int i=h[x];i!=-1;i=a[i].next)
    56     {
    57         u=a[i].y;
    58         if (vis[u]) continue;
    59         vis[u]=true;
    60         if (!match[u]||dfs(match[u]))
    61         {
    62             match[x]=u;
    63             match[u]=x;
    64             return true;
    65         }
    66     }
    67     return false;
    68 }
    69 
    70 int solve()
    71 {
    72     for (int i=1;i<=n+m;++i)
    73     {
    74         if (!match[i]) 
    75             mark[i]='N',work(i,0);
    76     }
    77 }
    78 
    79 int work(int x,int op)
    80 {
    81     int u;
    82     if (op==1) 
    83     {
    84         mark[x]='A';
    85         work(match[x],0);
    86         return 0;
    87     }
    88     mark[x]='N';
    89     for (int i=h[x];i!=-1;i=a[i].next)
    90     {
    91         u=a[i].y;
    92         if (mark[u]=='E') work(u,1);
    93     }
    94 }
    挫挫滴代码
  • 相关阅读:
    Java-用switch判断季节
    鼠标放在菜单上下拉列表
    web自学网站
    JS与树本(复杂)
    简单滑动下拉列表
    匿名对象 构造方法 重载 构造代码块 this 关键字
    数组 面向对象 成员变量和局部变量额区别
    静态修饰符 权限修饰符 设计模式 面向对象
    面向对象、匿名对象、构造方法
    java的基础知识运算符
  • 原文地址:https://www.cnblogs.com/yoyoball/p/7624368.html
Copyright © 2011-2022 走看看