题目链接:点击打开链接

题意:

给定n个点m条边的无向图

问图中是否存在 有且仅有一个简单环和一些树,且这些树的root都在这个简单环上。

瞎写了个点双。

==

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <vector>
#include <set>
using namespace std;
#define N 105
#define M 100005
#define inf 10000000
struct Edge{
int from,to,next;
}edge[2*M];
int head[N],edgenum;
int Low[N],DFN[N],Stack[N];//Belong数组的值是1~block
int Index,top;
int Belong[N],block;//新图的连通块标号(1~block)
bool Instack[N];
int bridge; //割桥数量
vector<int> bcc[N];
void addedge(int u,int v){
Edge E={u,v,head[u]}; edge[edgenum]=E; head[u] = edgenum++;
Edge E2={v,u,head[v]};edge[edgenum]=E2;head[v] = edgenum++;
}
void Tarjan(int u,int pre){
int v;
Low[u] = DFN[u] = ++Index;
Stack[top++] = u;
Instack[u] = true;
for(int i = head[u]; ~i ;i = edge[i].next){
v = edge[i].to;
// 假设重边有效的话以下这句改成: if(v == pre && pre_num == 0){pre_num++;continue;} pre_num在for上面定义 int pre_num=0;
if( v == pre )continue;
if( !DFN[v] ){
Tarjan(v,u);
if(Low[u] > Low[v])Low[u] = Low[v];
if(Low[v] > Low[u])
bridge++;
}
else if(Instack[v] && Low[u] > DFN[v])Low[u] = DFN[v];
}
if(Low[u] == DFN[u]){
block++;
bcc[block].clear();
do{
v = Stack[--top];
Instack[v] = false;
Belong[v] = block;
bcc[block].push_back(v);
}while( v != u );
}
}
void work(int l, int r){
memset(DFN,0,sizeof(DFN));
memset(Instack,false,sizeof(Instack));
Index = top = block = bridge = 0;
for(int i = l; i <= r; i++)if(!DFN[i])Tarjan(i,i);
}
vector<int>G[N];
void suodian(){
for(int i = 1; i <= block; i++)G[i].clear();
for(int i = 0; i < edgenum; i+=2){
int u = Belong[edge[i].from], v = Belong[edge[i].to];
if(u==v)continue;
G[u].push_back(v), G[v].push_back(u);
}
}
void init(){edgenum = 0; memset(head,-1,sizeof(head));} int n, m, vis[N], siz[N], f[N];
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
void Union(int x, int y){
int fx = find(x), fy = find(y);
if(fx==fy)return;
if(fx>fy)swap(fx,fy); f[fx] = fy;
}
bool dfs(int u){
vis[u] = 1;
bool ok = true;
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i]; if(vis[v])continue;
if(bcc[v].size()>1)ok = false;
if(dfs(v)==false)ok = false;
}
return ok;
}
set<int>myset;
bool solve(){
int i, u, v;
init();
for(i = 1; i <= n; i++)f[i] = i;
while(m--){
scanf("%d %d",&u,&v);
addedge(u, v);
Union(u,v);
}
myset.clear();
for(i = 1; i<= n; i++)myset.insert(find(i));
if(myset.size()>1)return false;
work(1, n);
suodian();
memset(vis, 0, sizeof vis);
memset(siz, 0, sizeof siz);
for(i = 0; i < edgenum; i+=2)
siz[u]+= (Belong[edge[i].from]==Belong[edge[i].to]); for(i = 1; i <= block; i++) if(!vis[i] && bcc[i].size()>1 && bcc[i].size()==siz[i] && G[i].size()>=3)
if(dfs(i))return true; return false;
}
int main(){
while(~scanf("%d %d", &n, &m))
solve() ? puts("FHTAGN!") : puts("NO");
return 0;
}
/*
6 6
1 2
2 3
3 1
4 5
5 6
6 4 */

Codeforces 104C Cthulhu dfs暴力 || 点双连通缩点的更多相关文章

  1. 边双连通缩点+树dp 2015 ACM Arabella Collegiate Programming Contest的Gym - 100676H

    http://codeforces.com/gym/100676/attachments 题目大意: 有n个城市,有m条路,每条路都有边长,如果某几个城市的路能组成一个环,那么在环中的这些城市就有传送 ...

  2. hdu 4612 Warm up 双连通缩点+树的直径

    首先双连通缩点建立新图(顺带求原图的总的桥数,事实上因为原图是一个强连通图,所以桥就等于缩点后的边) 此时得到的图类似树结构,对于新图求一次直径,也就是最长链. 我们新建的边就一定是连接这条最长链的首 ...

  3. UVA 10972 RevolC FaeLoN(边-双连通+缩点)

    很好的一道图论题,整整撸了一上午... 题意是给定一个无向图,要求将所有边变为有向边,求最少加入多少条有向边,使得该图强连通?这里先假设一个问题:给定一个无向子图,该子图具有怎样的性质才能使得将其无向 ...

  4. poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&&缩点】

    Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10141   Accepted: 503 ...

  5. POJ 3177 Redundant Paths (边双连通+缩点)

    <题目链接> <转载于 >>>  > 题目大意: 有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走.现已有m条路,求至少要新 ...

  6. POJ - 3177 Redundant Paths (边双连通缩点)

    题意:在一张图中最少可以添加几条边,使其中任意两点间都有两条不重复的路径(路径中任意一条边都不同). 分析:问题就是最少添加几条边,使其成为边双连通图.可以先将图中所有边双连通分量缩点,之后得到的就是 ...

  7. Hdu4005-The war(双连通缩点)

    In the war, the intelligence about the enemy is very important. Now, our troop has mastered the situ ...

  8. UVA-10972 RevolC FaeLoN (边双连通+缩点)

    题目大意:将n个点,m条边的无向图变成强连通图,最少需要加几条有向边. 题目分析:所谓强连通,就是无向图中任意两点可互达.找出所有的边连通分量,每一个边连通分量都是强连通的,那么缩点得到bcc图,只需 ...

  9. hdu4612(双连通缩点+树的直径)

    传送门:Warm up 题意:询问如何加一条边,使得剩下的桥的数目最少,输出数目. 分析:tarjan缩点后,重新建图得到一棵树,树上所有边都为桥,那么找出树的直径两个端点连上,必定减少的桥数量最多, ...

随机推荐

  1. Centos 7 编译php 7.2.10

    步骤一:安装依赖 yum install -y wget gcc gcc-c++ gd-devel zlib-devel libjpeg-devel libpng-devel libiconv-dev ...

  2. python初体验 ——>>> 模拟体育竞技

    python初体验 ——>>> 模拟体育竞技 一.排球训练营 1. 简介: 模拟不同的两个队伍进行排球的模拟比赛. 2. 模拟原理: 通过输入各自的能力值(Ⅰ),模拟比赛的进行( P ...

  3. Vijos1144 皇宫看守 (0/1/2三种状态的普通树形Dp)

    题意: 给出一个树以及一些覆盖每个点的花费,求每个点都能被自己被覆盖,或者相邻的点被覆盖的最小价值. 细节: 其实我乍一眼看过去还以为是 战略游戏 的复制版 可爱的战略游戏在这里QAQ(请原谅这波广告 ...

  4. 如何将表的行数赋值给变量(MySQL)

    delimiter $$ drop procedure if exists test_at $$ create definer=root@localhost procedure test_at() b ...

  5. HTML+CSS 制作HTML5标志图

    效果图如下:(是用代码写的,而不是图片!) 网上看到的代码. 看了下,就是CSS的transform属性的应用.加上定位等.组合在一起形成图片. 没什么难点,就是width,left等数据得根据HTM ...

  6. CI 安装时目录的安全处理

    如果你想通过隐藏 CodeIgniter 的文件位置来增加安全性,你可以将 system 和 application 目录修改为其他的名字,然后打开主目录下的 index.php 文件将 $syste ...

  7. 『NYIST』第八届河南省ACM竞赛训练赛[正式赛一]-CodeForces 237C,素数打表,二分查找

    C. Primes on Interval time limit per test 1 second memory limit per test 256 megabytes input standar ...

  8. 洛谷P1771 方程的解_NOI导刊2010提高(01)

    题目描述 佳佳碰到了一个难题,请你来帮忙解决. 对于不定方程a1+a2+…+ak-1+ak=g(x),其中k≥2且k∈N,x是正整数,g(x)=x^x mod 1000(即x^x除以1000的余数), ...

  9. redis哨兵模式配置

    java对redis的读写 依赖包:jedis.jar maven下: <!-- https://mvnrepository.com/artifact/redis.clients/jedis - ...

  10. Nginx,Apache,Tomcat区别

    Nginx:一款能承受高并发的HTTP服务器,异步的,多个连接(万级别)可以对应一个进程,进行响应.基于事件驱动模型. Nginx优点:负载均衡.反向代理.处理静态文件优势. Apache:相对于Ng ...