题目链接:点击打开链接

题意:

给定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. css3浏览器兼容的前缀

    -moz代表firefox浏览器私有属性 -ms代表ie浏览器私有属性 -webkit代表safari.chrome私有属性

  2. ZOJ - 1655 Transport Goods(单源最长路+迪杰斯特拉算法)

    题目: 有N-1个城市给首都(第N个城市)支援物资,有M条路,走每条路要耗费一定百分比(相对于这条路的起点的物资)的物资.问给定N-1个城市将要提供的物资,和每条路的消耗百分比.求能送到首都的最多的物 ...

  3. 6. 将单独表空间(File-Per-Table Tablespaces)复制到另一个实例

    6. 将单独表空间复制到另一个实例 本节介绍如何将单独表空间从一个MySQL实例复制 到另一个MySQL实例,也称为可传输表空间功能. 将InnoDB单独表空间复制到其他实例的原因有很多: - 在不对 ...

  4. nginx 集群

    Nginx是什么? Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器.一直纳闷这个X是怎么来 ...

  5. 条款18:让接口容易被正确使用,不易被误用(Make interface easy to use correctly and hard to use incorrectly)

    NOTE : 1.好的接口容易被正确使用,不容易被误用.应该让所有接口努力达成这些性质. 2.“促进正确使用”的办法包括接口的一致性,以及内置类型的行为兼容. 3.“阻止误用”的办法包括建立新类型/限 ...

  6. 第三天,小作业,表达式,while循环

    num += 1 等价于 num = num + 1num -= 1 等价于 num = num - 1num *= 2 等价于 num = num * 2num /= 2 等价于 num = num ...

  7. jQuery对象数据缓存Cache原理及jQuery.data详解

    网上有很多教你怎么使用jQuery.data(..)来实现数据缓存,但有两个用户经常使用的data([key],[value])和jQuery.data(element,[key],[value])几 ...

  8. Gym - 100548C The Problem Needs 3D Arrays (最大密度子图)

    TK在大多数 Unix平台.Windows平台和Macintosh系统都是预装好的,TKinter 模块是 Tk GUI 套件的标准Python接口.可实现Python的GUI编程. Tkinter模 ...

  9. 会修修的莫队--BZOJ2120: 数颜色

    $n \leq 10000$的数列,$m \leq 10000$个操作,一:单点修改:二:查区间不同数字个数.修改数$\leq 1000$,数字$\leq 1000000$. 我不会告诉您这是三种写法 ...

  10. vagrant的学习 之 Yii2

    vagrant的学习 之 Yii2 本文根据慕课网的视频教程练习,感谢慕课网! 慕课视频学习地址:https://www.imooc.com/video/14218. 慕课的参考文档地址:https: ...