zoukankan      html  css  js  c++  java
  • 二分图点染色 BestCoder 1st Anniversary($) 1004 Bipartite Graph

    题目传送门

     1 /*
     2   二分图点染色:这题就是将点分成两个集合就可以了,点染色用dfs做, 剩下的点放到点少的集合里去
     3     官方解答:首先二分图可以分成两类点X和Y, 完全二分图的边数就是|X|*|Y|.我们的目的是max{|X|*|Y|}, 并且|X|+|Y|=n.
     4     修正:实现多连通块染色,然后贪心选择,将两个集合个数差大的连通块优先添加,能尽量使得un*vn最大
     5  */
     6 #include <cstdio>
     7 #include <algorithm>
     8 #include <cstring>
     9 #include <vector>
    10 #include <map>
    11 using namespace std;
    12 
    13 const int MAXN = 1e4 + 10;
    14 const int MAXM = 1e5 + 10;
    15 const int INF = 0x3f3f3f3f;
    16 vector<int> G[MAXN];
    17 int col[2*MAXN];
    18 bool vis[MAXN];
    19 struct Block    {       //连通块
    20     int u, v;
    21     bool operator < (const Block &r) const  {
    22         return u - v > r.u - r.v;
    23     }
    24 }b[MAXN];
    25 int n, m, un, vn;
    26 
    27 void DFS(int u, int c)    {
    28     col[c]++; vis[u] = true;
    29     for (int i=0; i<G[u].size (); ++i)  {
    30         int v = G[u][i];
    31         if (vis[v]) continue;
    32         DFS (v, c ^ 1);
    33     }
    34 }
    35 
    36 int main(void)  {       //BestCoder 1st Anniversary($) 1004 Bipartite Graph
    37     //freopen ("D.in", "r", stdin);
    38 
    39     int T;  scanf ("%d", &T);
    40     while (T--) {
    41         scanf ("%d%d", &n, &m);
    42         for (int i=1; i<=n; ++i)    G[i].clear ();
    43         for (int i=1; i<=m; ++i)    {
    44             int u, v;   scanf ("%d%d", &u, &v);
    45             G[u].push_back (v); G[v].push_back (u);
    46         }
    47 
    48         int color = 0;
    49         memset (vis, false, sizeof (vis));
    50         memset (col, 0, sizeof (col));
    51         for (int i=1; i<=n; ++i)    {
    52             if (vis[i]) continue;
    53             DFS (i, color);    color += 2;
    54         }
    55         int cnt = 0;
    56         for (int i=0; i<color; i+=2) {
    57             b[++cnt].u = col[i];  b[cnt].v = col[i^1];
    58             if (b[cnt].u < b[cnt].v)    swap (b[cnt].u, b[cnt].v);
    59         }
    60         sort (b+1, b+1+cnt);
    61 
    62         un = vn = 0;
    63         for (int i=1; i<=cnt; ++i)  {
    64             if (un <= vn)   {
    65                 un += b[i].u;   vn += b[i].v;
    66             }
    67             else    {
    68                 un += b[i].v;   vn += b[i].u;
    69             }
    70         }
    71         printf ("%d
    ", un * vn - m);
    72     }
    73 
    74     return 0;
    75 }
    编译人生,运行世界!
  • 相关阅读:
    广东省第三届普通高中信息技术优质课交流评选活动参后感
    预说课
    arraylist和list的区别
    List 泛型类 详解
    C#中const和readonly的区别
    PHP array_walk() 函数
    栈,堆,代码区,全局(静态)区 ,常量区
    PHP_SELF、 SCRIPT_NAME、 REQUEST_URI区别
    c#中Dictionary、ArrayList、Hashtable和数组的区别(
    PHP文件包含语句 include、include_once、require、require_once
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4677177.html
Copyright © 2011-2022 走看看