Light OJ 1300 - Odd Personality
来源:互联网 发布:破坏公司网络罪 编辑:程序博客网 时间:2024/06/06 09:04
题意:
给定一个无向图,没有自环和重边,问图中总共有多少个点满足从这个点出发不经过重复的边且经过边的数目为奇数?
思路:
不经过重复的边回来,就是不经过桥,也就是这个点处于一个强连通分量中。
也就是求个强连通分量就好了,但是怎么判断是否存在路径为奇数呢?
也就是说强连通分量中是否存在奇环?直接染色?如何证明?
这里有个定理:强连通分量中如果存在奇环,那么这个连通分量中的所有点都在奇环中 其实相当好证明,你画个三元环,然后构造这个图,发现其他点走的路径如果是偶数,我可以选择在三元环里走路径为1的那一条,奇数呢?同理。。。所以有了这个定理本题就没什么好说的了。
代码:
#include <cstdio>#include <cstring>#include <queue>#include <algorithm>#include <iostream>#include <cmath>#include <map>#include <vector>#include <set>#include <string>#define PB push_back#define FT first#define SD second#define MP make_pair#define INF 0x3f3f3f3fusing namespace std;typedef long long LL;typedef unsigned long long ULL;typedef pair<int,int> P;const int N = 5 + 1e4 ,M = 10 + 4e4;int n, m, col[N];int DFN[N],low[N],st[N],Belong[N];bool instack[N];int ord,top,sccnum;int ans,tot,head[N];struct edge{ int to,next;}e[M];void init(){ ord = sccnum = top = tot = ans = 0; memset(DFN,-1,sizeof(DFN)); memset(low,-1,sizeof(low)); memset(head,-1,sizeof(head)); memset(col,-1,sizeof(col)); memset(Belong,0,sizeof(Belong));//所属分量初始化为0 memset(instack,0,sizeof(instack));}void addedge(int u,int v){ e[tot].to = v,e[tot].next = head[u],head[u] = tot++;}bool color(int u,int c){ col[u] = c; for(int i = head[u];i != -1;i = e[i].next) { int v = e[i].to; if(Belong[v] != sccnum) continue; if(col[v] == -1){ if(!color(v,!c)){ return false; } } else if(col[v] == c){ return false; } } return true;}void tarjan (int u,int fa){ DFN[u] = low[u] = ++ord; instack[u] = 1; st[top++] = u; for (int i = head[u]; i != -1; i = e[i].next){ int v = e[i].to; if(v == fa) continue; if (DFN[v] == -1){ tarjan (v,u); if (low[u] > low[v]) { low[u] = low[v]; } } else if (instack[v]){ low[u] = min(low[u], DFN[v]); } } int v, cnt = 0; if (DFN[u] == low[u]){ sccnum++; do{ v = st[--top]; Belong[v] = sccnum; instack[v] = 0, cnt ++; }while (v != u); if(cnt > 1 && !color(u,0)){ ans += cnt; } }}int main(){ int T, u, v, ca = 0; scanf("%d",&T); while(T --){ scanf("%d%d",&n,&m); init(); while(m --){ scanf("%d%d",&u,&v); addedge(u,v), addedge(v,u); } for(int i = 0;i < n;i ++) if(DFN[i] == -1) { tarjan(i, -1); } printf("Case %d: %d\n", ++ca, ans); } return 0;}
0 0
- Light OJ 1300 - Odd Personality
- Light OJ 1300 - Odd Personality (Tarjian求边双连通+二分图染色法判定奇圈)
- LightOJ 1300 - Odd Personality
- LightOJ - 1300 Odd Personality(边双连通+奇圈判定)
- personality
- light oj
- light oj
- Light OJ
- Light OJ
- Light OJ 1000
- Light OJ 1001
- Light OJ 1008
- Light OJ 1022
- Light OJ 1015
- Light OJ 1042
- light oj 1128
- Light OJ 1055 BFS
- Light OJ Beginners Problems
- What is pstate and turbo?
- 二叉树链表实现(有bug待查)---关于二叉树的思考
- Java中对于时间的操作
- 基于fabric和hg的自动化部署
- 10027---IO流 InputStream & Reader
- Light OJ 1300 - Odd Personality
- 模拟登陆的背后
- Struts2 局部类型转换和全局类型转换实践
- QT环境搭建,QT各个历史版本下载地址,QT SDK下载地址
- 最简单的安卓环境搭建
- 杭电-5586-最大子序列和
- Python基础(1)
- Python定时执行之Timer
- (NO.001)升级Xcode8 真机调试iOS10 报错“Could not find Developer Disk Image”解决办法