zoukankan      html  css  js  c++  java
  • 【Codeforces542E】Playing on Graph [Bfs][Dfs]

    Playing on Graph

    Time Limit: 20 Sec  Memory Limit: 512 MB

    Description

      

    Input

      

    Output

      

    Sample Input

      5 4
      1 2
      2 3
      3 4
      3 5

    Sample Output

      3

    HINT

      n <= 1000, m <= 10^5

    Solution

      我们先考虑无解的情况。显然就是图中有奇环的时候无解,因为你将奇环上两点缩起来,最后必定会变成一个三元环,而三元环是不能合并的。所以就可以Dfs黑白染色一下,若是搜到两个同色的话即是有奇环

      我们再考虑如何构造一种方案,显然,我们先找出一个点root,然后将所有 dist 相同的并起来,这样是一组可行解。可以发现,所有的方案都可以由这种方式构造出来。

      那么这时候,确定一点  为 root 的时候,贡献显然等于最大的 dist。那么我们将所有点都确定为root一遍,然后Bfs求一下dist,取出最大dist,就可以得到一个联通块的答案了。

      显然可以有多个连通块Ans = Σ每个连通块的答案

    Code

     1 #include<iostream>  
     2 #include<string>  
     3 #include<algorithm>  
     4 #include<cstdio>  
     5 #include<cstring>  
     6 #include<cstdlib>  
     7 #include<queue>
     8 using namespace std;
     9 typedef long long s64;
    10  
    11 const int ONE = 800005;
    12 const int Base = 2005;
    13 
    14 int n, m;
    15 int x, y;
    16 int next[ONE], first[ONE], go[ONE], tot;
    17 int vis[ONE], col[ONE];
    18 int pd;
    19 int vis_a[ONE], record[ONE], num, dist[ONE];
    20 int Ans;
    21 queue <int> q;
    22 
    23 int get()
    24 { 
    25         int res;char c; 
    26         while( (c=getchar())<48 || c>57 );
    27         res=c-48;  
    28         while( (c=getchar())>=48 && c<=57 ) 
    29         res=res*10+c-48; 
    30         return res; 
    31 } 
    32 
    33 void Add(int u, int v)
    34 {
    35         next[++tot] = first[u], first[u] = tot, go[tot] = v;
    36         next[++tot] = first[v], first[v] = tot, go[tot] = u;
    37 }
    38 
    39 void Dfs(int u, int color)
    40 {
    41         vis[u] = 1;
    42         col[u] = color;
    43         record[++num] = u;
    44         for(int e = first[u]; e; e = next[e])
    45         {
    46             int v = go[e];
    47             if(!vis[v]) Dfs(v, color ^ 1);
    48             else pd |= col[v] == col[u];
    49         }
    50 }
    51 
    52 int Bfs(int S)
    53 {
    54         for(int i = 1; i <= n; i++) dist[i] = vis_a[i] = 0;
    55         dist[S] = 0, vis_a[S] = 1, q.push(S);
    56         while(!q.empty())
    57         {
    58             int u = q.front();    q.pop();
    59             for(int e = first[u]; e; e = next[e])
    60             {
    61                 int v = go[e];
    62                 if(vis_a[v]) continue;
    63                 vis_a[v] = 1;
    64                 dist[v] = dist[u] + 1;
    65                 q.push(v);
    66             }
    67         }
    68 
    69         int res = 0;
    70         for(int i = 1; i <= n; i++)
    71             res = max(res, dist[i]);
    72         return res;
    73 }
    74 
    75 int main()
    76 {
    77         n = get();    m = get();
    78         for(int i = 1; i <= m; i++)
    79         {
    80             x = get(), y = get();
    81             Add(x, y);
    82         }
    83 
    84         for(int i = 1; i <= n; i++)
    85             if(!vis[i])
    86             {
    87                 num = 0;
    88                 Dfs(i, 0);
    89                 if(pd == 1) {printf("-1"); return 0;}
    90 
    91                 int res = 0;
    92                 for(int j = 1; j <= num; j++)
    93                     res = max(res, Bfs(record[j]));
    94                 Ans += res;
    95             }
    96 
    97         printf("%d", Ans);
    98 }
    View Code

    un[ʌn]


    • n. (Un)人名;(柬)温
    • pron. 家伙,东西
  • 相关阅读:
    printf函数实现的深入剖析
    rhel/centos播放mp3文件
    GRUB(GRand Unified Boot loader)引导加载程序
    NAT DHCP WWW rc.local
    论文 毕业设计 相关 用语 评语
    Linux禁止单用户模式(single)来增强系统安全
    Kernel command using Linux system calls
    GNU-ld链接脚本浅析
    AT&T汇编心得之间接寻址和LEA指令
    Linux 汇编语言开发指南
  • 原文地址:https://www.cnblogs.com/BearChild/p/7683114.html
Copyright © 2011-2022 走看看