zoukankan      html  css  js  c++  java
  • UOJ 79 带花树入门

    从前一个和谐的班级,所有人都是搞OI的。有 nn 个是男生,有 00 个是女生。男生编号分别为 1,…,n1,…,n。

    现在老师想把他们分成若干个两人小组写动态仙人掌,一个人负责搬砖另一个人负责吐槽。每个人至多属于一个小组。

    有若干个这样的条件:第 vv 个男生和第 uu 个男生愿意组成小组。

    请问这个班级里最多产生多少个小组?
    输入格式

    第一行两个正整数,n,mn,m。保证 n≥2n≥2。

    接下来 mm 行,每行两个整数 v,uv,u 表示第 vv 个男生和第 uu 个男生愿意组成小组。保证 1≤v,u≤n1≤v,u≤n,保证 v≠uv≠u,保证同一个条件不会出现两次。
    输出格式

    第一行一个整数,表示最多产生多少个小组。

    接下来一行 nn 个整数,描述一组最优方案。第 vv 个整数表示 vv 号男生所在小组的另一个男生的编号。如果 vv 号男生没有小组请输出 00。
    样例一
    input

    10 20
    9 2
    7 6
    10 8
    3 9
    1 10
    7 1
    10 9
    8 6
    8 2
    8 1
    3 1
    7 5
    4 7
    5 9
    7 8
    10 4
    9 1
    4 8
    6 3
    2 5

    output

    5
    9 5 6 10 2 3 8 7 1 4

    样例二
    input

    5 4
    1 5
    4 2
    2 1
    4 3

    output

    2
    2 1 4 3 0

    限制与约定

    1≤n≤500,1≤m≤124750。

    时间限制:1s

    空间限制:256MB

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<iostream>
      6 #include<algorithm>
      7 #include<vector>
      8 #include<queue>
      9 
     10 using namespace std;
     11 
     12 #define LL long long
     13 #define pb push_back
     14 #define Set(a, v) memset(a, v, sizeof(a))
     15 #define For(i, a, b) for(int i = (a); i <= (int)(b); i++)
     16 #define Forr(i, a, b) for(int i = (a); i >= (int)(b); i--)
     17 
     18 #define MAXN (500+5)
     19 
     20 struct BlossomTree{
     21     vector<int> G[MAXN];
     22     queue<int> q;
     23     int n;
     24     int pre[MAXN], link[MAXN], col[MAXN], fa[MAXN];
     25     bool vis[MAXN];
     26 
     27     void init(int rn){
     28         n = rn;
     29         Set(link, 0);
     30         For(i, 0, n) G[i].clear();
     31     }
     32 
     33     void Addedges(int u, int v){
     34         G[u].pb(v); G[v].pb(u);
     35     }
     36 
     37     int find(int x){
     38         return x == fa[x]? x: (fa[x] = find(fa[x]));
     39     }
     40 
     41     void Combine(int u, int lca){
     42         while(u != lca){
     43             int f = link[u], g = pre[f];
     44             if(find(g) != lca) pre[g] = f; //put the rever edge
     45             if(col[f] == 1) col[f] = 2, q.push(f);
     46             fa[find(u)] = find(f); fa[find(f)] = find(g);
     47 
     48             u = pre[link[u]];
     49         }
     50     }
     51 
     52     void Contract(int u, int v){
     53         Set(vis, 0);
     54 
     55         int lca = 0;
     56         for(int i = u; i; i = pre[link[i]]) i = find(i), vis[i] = true;
     57         for(int i = v; i; i = pre[link[i]]){
     58             i = find(i);
     59             if(vis[i]){lca = i; break;}
     60         }
     61 
     62         if(find(u) != lca) pre[u] = v;
     63         if(find(v) != lca) pre[v] = u;
     64         Combine(u, lca); Combine(v, lca);
     65     }
     66 
     67     void Bfs(int s){
     68         while(!q.empty()) q.pop();
     69         Set(col, 0); Set(pre, 0);
     70         For(i, 1, n) fa[i] = i;
     71 
     72         q.push(s); col[s] = 1;
     73         while(!q.empty()){
     74             int now = q.front(); q.pop();
     75 
     76             For(i, 0, G[now].size()-1){
     77                 int v = G[now][i];
     78                 if(find(now)==find(v) || link[now]==v || col[v]==1) continue;
     79 
     80                 if(col[v] == 2) Contract(now, v);  
     81                 else if(link[v]){
     82                     pre[v] = now; col[v] = 1;
     83                     col[link[v]] = 2;
     84                     q.push(link[v]);
     85                 }else{
     86                     pre[v] = now;
     87 
     88                     int g = link[now], f = now, o = v;
     89                     while(o){
     90                         link[f] = o; link[o] = f;
     91                         o = g; f = pre[o]; g = link[f];
     92                     }
     93                     return;
     94                 }
     95             }
     96         }
     97     }
     98 
     99     int MaxMatch(){
    100         For(i, 1, n) if(!link[i]) Bfs(i);
    101 
    102         int ret = 0;
    103         For(i, 1, n) if(link[i]) ret++;
    104         return ret/2;
    105     }
    106 
    107     void print(){
    108         printf("%d", link[1]);
    109         For(i, 2, n) printf(" %d", link[i]);
    110         printf("\n");
    111     }
    112 }BT;
    113 
    114 int main(){
    115     int n, m;
    116     scanf("%d%d", &n, &m);
    117 
    118     BT.init(n);
    119     For(i, 1, m){
    120         int u, v;
    121         scanf("%d%d", &u, &v);
    122         BT.Addedges(u, v);
    123     }
    124 
    125     printf("%d\n", BT.MaxMatch());
    126     BT.print();
    127 
    128     return 0;
    129 }
    Miaomiao❤ ++RP
  • 相关阅读:
    让程序用自定义的菜单自定义菜单AVKON_VIEW,CBA,MENU_BAR,MENU_PANE
    symbian 菜单不显示的原因
    子类中调用父类的带参数的构造函数|子类构造函数调用父类构造函数 的说明
    symbian 设置 透明背景
    IOS App资源路径
    Nonblock I/O 及其使用
    CEikStatusPane MakeVisible kernexec 3错误
    把mapinfo图层的经纬度信息导出来的办法
    解决安装macports,不能更新的问题
    jpg结构解析
  • 原文地址:https://www.cnblogs.com/miaomiao1220/p/6642357.html
Copyright © 2011-2022 走看看