题解

大意是给出一张图,然后建一张新图,新图的点标号是(a,b)
如果a和c有一条边,b和d有一条边,那么(a,b)和(c,d)之间有一条边

我们把这道题当成这道题来做,给出两张图,如果第一张图有边(a,c),第二张图有边(b,d),那么第三张图上有边(a,b)(c,d)

如果某张图只有一个点,那么答案就是另一张图的点数

然后我们发现对于某两个点对(a,c),(b,d)如果有一条长度为l的路径,那么(a,b)(c,d)一定可以联通
但是我们发现我们经过的路径可以不是简单路径,也就是我们反复走一条边,那么我们只和路径长度的奇偶性有关了

很容易想到二分图,如果两张图都是二分图且联通的话,那么第三张图联通分量的个数是2
分别是\(S_a * T_b \cup T_a * S_b\)和\(S_a * S_b \cup T_a * T_b\)

而两张图都是非二分图且联通的话,任意路径的奇偶性都可以互相转化,所以整张图就是一个联通块
那么我们求出两个图的孤立点个数\(i_A,i_B\),两个图的非二分图联通块个数\(p_A,p_B\),两个图的二分图联通块个数\(q_A,q_B\)
答案就是
\(i_Ai_B + i_A(N_B - i_B) + i_B(N_A - i_A) + p_Ap_B + p_Aq_B + p_Bq_A + 2q_Aq_B\)

代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#include <bitset>
#include <queue>
#define enter putchar('\n')
#define space putchar(' ')
//#define ivorysi
#define pb push_back
#define mo 974711
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define MAXN 200005
#define eps 1e-12
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;char c = getchar();T f = 1;
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 - '0' + c;
    c = getchar();
    }
    res = res * f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) out(x / 10);
    putchar('0' + x % 10);
}
int N,M,I,P,Q;
struct node {
    int next,to;
}E[MAXN * 2];
int head[MAXN],sumE,col[MAXN];
bool vis[MAXN];
void dfs(int u) {
    vis[u] = 1;
    for(int i = head[u] ; i ; i = E[i].next) {
    int v = E[i].to;
    if(!vis[v]) {
        dfs(v);
    }
    }
}
bool paint(int u) {
    if(!col[u]) col[u] = 2;
    for(int i = head[u] ; i; i = E[i].next) {
    int v = E[i].to;
    if(!col[v]) {col[v] = col[u] ^ 1;if(!paint(v)) return false;}
    else if(col[v] == col[u]) return false;
    }
    return true;
}
void add(int u,int v) {
    E[++sumE].to = v;
    E[sumE].next = head[u];
    head[u] = sumE;
}
void Solve() {
    read(N);read(M);
    int u,v;
    for(int i = 1 ; i <= M ; ++i) {
    read(u);read(v);
    add(u,v);add(v,u);
    }
    for(int i = 1 ; i <= N ; ++i) {
    if(!head[i]) ++I;
    else if(!vis[i]){
        dfs(i);
        if(paint(i)) ++Q;
        else ++P;
    }
    }
    int64 ans = 1LL * I * I + 2LL * I * (N - I);
    ans += 1LL * P * P + 2LL * P * Q + 2LL * Q * Q;
    out(ans);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

最新文章

  1. 7.10 数据注解特性--NotMapped
  2. 使用js批量选中功能实现更改数据库中的status状态值(批量展示)
  3. oracle+ibatis 批量插入-支持序列自增
  4. 为什么说Parcelable 比Serializable更高效
  5. Linux学习笔记28——消息队列
  6. RHEL 6.3使用CentOS yum源 (redhat yum安装失败)
  7. 做外贸,独立B2C商城好,还是平台好
  8. VMware Workstation 12 Pro 之安装林耐斯StartOS X64系统
  9. Python Counter class
  10. java中有关流操作的类和接口
  11. AngularJS1.X学习笔记9-自定义指令(中)
  12. struts2 可以用ognl拿到值而不可以用el拿到值的解决方法
  13. opencv图像融合(给人脸添加一个眼镜)
  14. Flume初入门简单配置与使用
  15. jackSon注解– @JsonInclude 注解不返回null值字段
  16. Git的一些基本操作和命令
  17. 转:变手把手教你玩转SOCKET模型之重叠I/O篇
  18. Jenkins Gitlab持续集成打包平台搭建
  19. HDU 6201 transaction transaction transaction(树形DP)
  20. Kettle中配置oracle RAC

热门文章

  1. 转:String StringBuffer StringBuilder区别
  2. React.js基础入门
  3. mysql 复制表数据,表结构的3种方法
  4. 基于Ubuntu16.04搭建WordPress
  5. Java事件基础
  6. 【总结】CSS透明度大汇总
  7. 20155301 2016-2017-2 《Java程序设计》第5周学习总结
  8. session使用
  9. vue组件之间传值方式解析
  10. 脚本病毒分析扫描专题1-VBA代码阅读扫盲、宏病毒分析