zoukankan      html  css  js  c++  java
  • CODE FESTIVAL 2017 qual B C

    CODE FESTIVAL 2017 qual B C - 3 Steps

    题意:给定一个n个结点m条边的无向图,若两点间走三步可以到,那么两点间可以直接连一条边,已经有边的不能连,问一共最多能连多少条边。

    题解:其实我不知道二分图的实际算法,网上有人说这可以看成是否是二分图来做。

         有人给出了个性质(没发现>_<):相邻奇数长度的两个点一定能连边

       二分图就是一个图的结点分别在两个不相交的集合S,T中,且每条边都在两个集合中。(不严谨说法)如果是二分图,那么能连的边数就是|S|*|T|-m。

       如果不是二分图,那么每个结点与其它结点都可以连边,结果就是n*(n-1)/2-m

       好像dfs是什么二分图的染色,感觉就是把边分成0,1两个组(集合)。

       结果很大,要用longlong,而且用exit(0)直接退出程序会方便很多。

         18行的意思是v不是与u不相同的颜色,也就是u,v同色,想想看u,v同色且相连,说明连接u,v的边就只在一个集合中,那就不是二分图了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<vector>
     5 #include<algorithm>
     6 using namespace std;
     7 typedef long long ll;
     8 const int maxn=100010;
     9 vector<int> edge[maxn*2];
    10 int tot,m,n,c[maxn];
    11 
    12 void dfs(int u,int col)
    13 {
    14     c[u]=col;
    15     for(int i=0;i<edge[u].size();i++){
    16         int v=edge[u][i];
    17         if(c[v]==-1) dfs(v,!col);
    18         if(c[v]!=!col){
    19             cout<<1ll*n*(n-1)/2-m<<endl;
    20             exit(0);
    21         }
    22     }
    23 }
    24 
    25 int main()
    26 {
    27     scanf("%d%d",&n,&m);
    28     memset(c,-1,sizeof(c));
    29     for(int i=0;i<m;i++){
    30         int u,v;
    31         scanf("%d%d",&u,&v);
    32         edge[u].push_back(v);
    33         edge[v].push_back(u);
    34     }
    35     dfs(1,0);
    36     int b=0,w=0;
    37     for(int i=1;i<=n;i++)
    38         if (c[i]) b++;
    39     else w++;
    40     cout<<1ll*b*w-m<<endl;
    41     return 0;
    42 }
  • 相关阅读:
    NSThread 多线程 三种方式
    CABasicAnimation 核心动画
    图片圆角属性
    GCD
    IOS 推送
    IOS 截图
    UIImage 截图
    UIImageView 动画
    AFN 判断网络状态
    Template 模式
  • 原文地址:https://www.cnblogs.com/zxhyxiao/p/7663343.html
Copyright © 2011-2022 走看看