• 3 Steps(二分图)


    C - 3 Steps


    Time limit : 2sec / Memory limit : 256MB

    Score : 500 points

    Problem Statement

    Rng has a connected undirected graph with N vertices. Currently, there are M edges in the graph, and the i-th edge connects Vertices Ai and Bi.

    Rng will add new edges to the graph by repeating the following operation:

    • Operation: Choose u and v (uv) such that Vertex v can be reached by traversing exactly three edges from Vertex u, and add an edge connecting Vertices u and v. It is not allowed to add an edge if there is already an edge connecting Vertices u and v.

    Find the maximum possible number of edges that can be added.

    Constraints

    • 2≤N≤105
    • 1≤M≤105
    • 1≤Ai,BiN
    • The graph has no self-loops or multiple edges.
    • The graph is connected.

    Input

    Input is given from Standard Input in the following format:

    N M
    A1 B1
    A2 B2
    :
    AM BM
    

    Output

    Find the maximum possible number of edges that can be added.


    Sample Input 1

    Copy
    6 5
    1 2
    2 3
    3 4
    4 5
    5 6
    

    Sample Output 1

    Copy
    4
    

    If we add edges as shown below, four edges can be added, and no more.


    Sample Input 2

    Copy
    5 5
    1 2
    2 3
    3 1
    5 4
    5 1
    

    Sample Output 2

    Copy
    5
    

    Five edges can be added, for example, as follows:

    • Add an edge connecting Vertex 5 and Vertex 3.
    • Add an edge connecting Vertex 5 and Vertex 2.
    • Add an edge connecting Vertex 4 and Vertex 1.
    • Add an edge connecting Vertex 4 and Vertex 2.
    • Add an edge connecting Vertex 4 and Vertex 3.

    //Atcoder的题目还是有新意啊,可以收获不少

    题意: n 个点 m 条边, 组成一个无向连通图,重复操作, 如果 a 点到 b 点距离为 3 ,并且没有连回 a ,就添加一条 a - b 的边。没有自环,问最多能添加几条边。

    分析可知,如有图有奇数环,必然可加成完全图

    如果图是二分图,则会变成完全二分图,

    否则最终变为完全图

    二分图dfs染色即可

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 # define LL          long long
     4 # define pr          pair
     5 # define mkp         make_pair
     6 # define lowbit(x)   ((x)&(-x))
     7 # define PI          acos(-1.0)
     8 # define INF         0x3f3f3f3f3f3f3f3f
     9 # define eps         1e-8
    10 # define MOD         1000000007
    11  
    12 inline int scan() {
    13     int x=0,f=1; char ch=getchar();
    14     while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    15     while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
    16     return x*f;
    17 }
    18 inline void Out(int a) {
    19     if(a<0) {putchar('-'); a=-a;}
    20     if(a>=10) Out(a/10);
    21     putchar(a%10+'0');
    22 }
    23 # define MX 100005
    24 /**************************/
    25 int n,m;
    26 vector<int> G[MX];
    27 int clo[MX];
    28  
    29 bool check()
    30 {
    31     bool ok=0;
    32     for (int i=1;i<=n;i++)
    33     {
    34         if (G[i].size()>=2)
    35         {
    36             if (ok) return 1;
    37             ok=1;
    38         }
    39     }
    40     return 0;
    41 }
    42  
    43 int dfs(int p,int s,int pre)
    44 {
    45     clo[p] = s%2+1;
    46     for (int i=0;i<G[p].size();i++)
    47     {
    48         int v = G[p][i];
    49         if (v==pre) continue;
    50         if (!clo[v])
    51         {
    52             if (!dfs(v,s+1,p))
    53                 return 0;
    54         }
    55         else if(clo[v]==clo[p]) return 0;
    56     }
    57     return 1;
    58 }
    59  
    60 int bipartite()
    61 {
    62     memset(clo,0,sizeof(clo));
    63     if (!dfs(1,1,-1)) return 0;
    64     return 1;
    65 }
    66  
    67 int main()
    68 {
    69     while(scanf("%d%d",&n,&m)!=EOF)
    70     {
    71         for (int i=1;i<=n;i++) G[i].clear();
    72  
    73         for (int i=1;i<=m;i++)
    74         {
    75             int x,y;
    76             scanf("%d%d",&x,&y);
    77             G[x].push_back(y);
    78             G[y].push_back(x);
    79         }
    80         if (!check())
    81             printf("0
    ");
    82         else if (!bipartite())
    83             printf("%lld
    ",(LL)n*(n-1)/2-m);
    84         else
    85         {
    86             LL b=0,w=0;
    87             for (int i=1;i<=n;i++)
    88             {
    89                 if (clo[i]==1) b++;
    90                 else w++;
    91             }
    92             printf("%lld
    ",b*w-m);
    93         }
    94     }
    95     return 0;
    96 }
    View Code
  • 相关阅读:
    系统进程查看 --- 微软官方出品
    Chrome 浏览器网页保存为PDF文件
    Chrome Google浏览器下载
    最强Android书 架构大剖析 作者网站
    腾讯暑期夏令营之旅
    轨迹记录App是怎样对定位轨迹进行过滤、优化和平滑处理的
    android-8~23 View.java
    android-23 View.java
    The server encountered an internal error that prevented it from fulfilling this request.
    Android Event
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/7657659.html
Copyright © 2020-2023  润新知