Codeforces 557D - Vitaly and Cycle (DFS染色)
2015-07-27 10:31
447 查看
很容易想到最多只需要添加3条边。
1.如果M==0,那么任选三个点连接3条边
2.如果所有连通分量大小均小于等于2,那么任选一个连通分量和一个点连2条边
3.如果本身存在奇圈(DFS过程中父节点和子节点颜色一样),那么答案是0 1
4.除此以外所有情况均可以只连一条边。
把图在DFS的过程中按照一黑一白染色,那么同一连通分量中的相同颜色的点连线均可构成奇圈。所以DFS时维护一下黑白点的数量即可。
注意,不同连通分量间的点颜色相同也不能连边。
代码:
1.如果M==0,那么任选三个点连接3条边
2.如果所有连通分量大小均小于等于2,那么任选一个连通分量和一个点连2条边
3.如果本身存在奇圈(DFS过程中父节点和子节点颜色一样),那么答案是0 1
4.除此以外所有情况均可以只连一条边。
把图在DFS的过程中按照一黑一白染色,那么同一连通分量中的相同颜色的点连线均可构成奇圈。所以DFS时维护一下黑白点的数量即可。
注意,不同连通分量间的点颜色相同也不能连边。
代码:
#include <iostream> #include <cstring> #include <cstdio> #include <vector> using namespace std; #define maxn 100005 #define maxm 100005 #define INF 100000000 #define LL long long bool vis[maxn]; int N,M; vector <int> G[maxn]; int odd,even; bool loop=0; bool bin=0; int ps[maxn]; void dfs(int n,int cur){ if(G .size()>=2) bin=1; if(cur&1){ odd++; ps =1;} else { even++; ps =0;} for(int i=0;i<G .size();i++){ int nw=G [i]; if(!vis[nw]){ vis[nw]=1; dfs(nw,cur+1); } if(ps[nw]==ps ) loop=1; } } int main(){ scanf("%d%d",&N,&M); odd=even=0; for(int i=0;i<M;i++){ int s,t; scanf("%d%d",&s,&t); G[s].push_back(t); G[t].push_back(s); } if(M==0){ LL res=1ll*N*(N-1)*(N-2)/6; printf("3 %lld\n",res); return 0; } LL res=0; for(int i=1;i<=N;i++){ if(!vis[i]){ vis[i]=1; odd=even=0; dfs(i,0); res+=1ll*odd*(odd-1)/2+1ll*even*(even-1)/2; } } if(loop){ printf("0 1\n"); return 0; } if(!bin){ printf("2 %lld\n",1ll*M*(N-2)); return 0; } printf("1 %lld\n",res); return 0; }
相关文章推荐
- Android完全退出应用程序的方法
- 超简洁代码实现CircleImageView
- iOS app调试
- Unity 之 C# 利用回调函数实现C++匿名函数
- 详解udev
- JAVA基础针对自己薄弱环节总结01(循环之前的知识)
- hdu 5312 Sequence 三角形数
- Eclipse导入Hadoop源码项目
- Android休眠唤醒实例(自用)
- POJ 2823 Sliding Window 单调队列
- stack栈
- iOS面试题小结
- zendstudio 声明变量类型,让变量自动方法提示
- 教你在PHPStorm中配置Xdebug
- js加载函数addLoadEvent()
- 使用Shiro实现登录成功后跳转到之前的页面
- 机房收费系统之将数据导出到Excel
- 插入排序
- Python中map()函数
- CodeForces 363A - Soroban