题目链接

题意:T组测试样例,每组样例给出一个N,表示(编号为0~N-1)的点有向图,随后给出这个有向图的边,每行是一个u和v,当u==0且v==0时边的输入结束.当每组两个条件时,输出YES,否则输出NO.

条件一:该图是一个强连通图;

条件二:该图中每条边都只属于一个环,即不能被多个环遍历到;

题解:对于这个题目,我们首先需要使用强连通图的Tarjan算法跑一遍强连通分量,判断该图的强连通分量是否只有一个,在是的情况下再对这个图跑所有环,将每次路过的路径边都存储在map<edge,int>中,int是指该边访问次数,最后遍历map中的所有边,若是访问次数都是1次,不存在被访问次数大于1的边,那么就可以输出YES,否则其他所有情况都是输出NO.

代码如下:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<map>
#include<vector>
using namespace std;
#define ll long long
const int maxn = 20005;
struct Tarjan {int n;                                      //点的个数vector<int>e[maxn];                         //邻接表存图int DFN[maxn], LOW[maxn];int index;                                  //编辑计数器int stk[maxn];                              //栈bool ins[maxn];                             //记录点是否在栈中int top;vector<vector<int> >ans; void init(int N) {                          //初始化n = N;ans.clear();for (int i = 1; i <= n; i++)e[i].clear();top = 0;index = 0;memset(DFN, -1, sizeof(DFN));memset(ins, 0, sizeof(ins));}void add_edge(int u, int v) {                //添加边e[u].push_back(v);}void dfs(int u) {                            //从u点开始搜索DFN[u] = LOW[u] = ++index;stk[top++] = u;                          //为了记录这个连通分量中的节点ins[u] = true;for (int i = 0; i < e[u].size(); i++) {int v = e[u][i];if (DFN[v] == -1) {dfs(v);LOW[u] = min(LOW[u], LOW[v]);}else if (ins[v])LOW[u] = min(LOW[u], DFN[v]);}if (DFN[u] == LOW[u]) {                   //当DFN==LOW时说明stk中点可以形成一个强连通分量vector<int>q;int v = stk[top - 1];while (u != v) {q.push_back(v);ins[v] = false;top--;v = stk[top - 1];}q.push_back(u);ins[u] = false;top--;ans.push_back(q);}}void solve() {                                //运行该函数后产生答案for (int i = 1; i <= n; i++)if (DFN[i] == -1) dfs(i);}
}T;
struct Check {struct edge {int u, v;edge(){}edge(int uu,int vv):u(uu),v(vv){}bool operator < (const edge &a)const {if (u != a.u) return u < a.u;return v < a.v;}}stk[50005];                                  //用于存储路径int n;int top;bool vis[maxn];map<edge, int>mp;                             //用于记录每条边的使用次数void init(int nn) {                           //初始化n = nn;top = 0;mp.clear();memset(vis, 0, sizeof(vis));}void dfs(int u) {                              //dfs将该强连通图的所有环都跑一遍vis[u] = true;for (int i = 0; i < T.e[u].size(); i++) {int v = T.e[u][i];stk[top++] = edge(u, v);if (!vis[v]) dfs(v);else {int j;for (j = top - 1; stk[j].u != v; j--)mp[stk[j]]++;mp[stk[j]]++;}}vis[u] = false;                           //注意需要刷新掉,不然下次无法访问}bool check() {                                //dfs后,若是存在某条路径被走过大于一次为falsedfs(1);for (map<edge, int>::iterator it = mp.begin(); it != mp.end(); it++)if ((*it).second > 1)return false;return true;}
}C;
int main() {int t, n;scanf("%d", &t);while (t--) {scanf("%d", &n);int u, v;T.init(n);                                //Tarjan初始化while (~scanf("%d%d",&u,&v)&&(u||v))      //建有向图T.add_edge(u+1, v+1);        T.solve();                                //获得该有向图的所有强连通分量bool key;if (T.ans.size() == 1) {C.init(n);                            //判断结构体初始化key = C.check();                      //调用判断结构体函数}else key = false;if (key) printf("YES\n");else printf("NO\n");    }return 0;
}

HDU - 3594 Cactus (强连通缩点+STL)相关推荐

  1. HDU - 3594 Cactus (仙人掌图)

    题意: 给出一个图,判断该图是不是仙人掌图. 分析: 给出仙人掌的详解:https://files-cdn.cnblogs.com/files/ambition/cactus_solution.pdf ...

  2. HDU 3594 Cactus(有向仙人掌图判断)

    题目链接 题意 判断一个有向图是不是仙人掌图 思路 思路看这 代码看这 据说数据水,这个比较详细应该正确 tarjan 先判断图是否强连通 再判断是否为仙人掌 假设图强连通,结论如下 仙人掌图的 DF ...

  3. HDU - 4685 Prince and Princess(强连通缩点+二分图完备匹配)

    题目链接:点击查看 题目大意:给出n个王子和m个公主,每个王子都有喜欢的公主,题目需要我们在尽可能多的王子可以匹配到喜欢的公主的情况下,求出每个王子所能娶的所有公主,必须保证王子娶了其中任何一个之后, ...

  4. Poj 2186 Popular Cows(Tarjan 强连通缩点)

    传送门:Poj 2186 题意:给你n头牛,m种关系,A牛认为B牛是popular的,B牛认为C牛是popular的,则A也认为C是popular的,问最终有几头被所有牛认为是popular的牛 题解 ...

  5. BZOJ1051 [HAOI2006]受欢迎的牛 Tarjan 强连通缩点

    欢迎访问~原文出处--博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1051 题意概括 有n只牛,有m个羡慕关系. 羡慕关系具有传递性. 如果A羡慕B,B羡慕C,那么我们 ...

  6. 2019ICPC(银川) - Delivery Route(强连通缩点+分块最短路)

    题目链接:点击查看 题目大意:给出n个点和m条边构成的图,每条边都有权值,其中m1条边是双向的,且权值非负,有m2条边是单向的,且权值可负,现在要求从给定起点st到其他每个点的最短路,若不存在路径则输 ...

  7. POJ - 1904 King's Quest(强连通缩点)

    题目链接:点击查看 题目大意:给出n个王子和n个公主,每个王子都有喜欢的公主,每个王子初始时都娶到了一位喜欢的公主,题目需要我们求出每个王子所能娶的所有公主,必须保证王子娶了其中任何一个之后,其他的王 ...

  8. POJ - 1236 Network of Schools(强连通缩点)

    题目链接:点击查看 题目大意:一个学校连接在一个计算机网络上,学校之间存在软件支援协议,每个学校都有它应支援的学校名单(学校A支援学校B,并不表示学校B一定支援学校A).当某校获得一个新软件时,无论是 ...

  9. 有向图缩点:tarjan强连通缩点(模板)

    SCC强连通缩点:(用之前记得init) 可以将有向图转换为一个 DAG 图,然后进行拓扑 const int N=1e4+100;const int M=1e5+100;struct Egde {i ...

最新文章

  1. php error_reporting 详解
  2. signature=dff897e1da6b42a8e9483e18ff19fcde,Vídeo Institucional: Ingresse1
  3. 《D3.js数据可视化实战手册》—— 1.1 简介
  4. Visual Studio Code 使用 ESLint 增强代码风格检查 - gyzhao - 博客园
  5. 力争营收渠道多样化,Line 向自拍应用 Snow 投资 4500 万美元
  6. 【拿不到offer全额退款】人工智能与 NLP / CV 第三期课程培训招生
  7. React与ES6(一)开篇介绍
  8. Linux0.11 kernel/exit.c中的free_page_tables()
  9. 使用天地图api访问本地wms
  10. VS2005 添加lib 的方法
  11. java命令行导出、导入sql文件
  12. android 设置锁屏壁纸
  13. java rnn生成古诗_基于循环神经网络(RNN)的古诗生成器
  14. 谷歌浏览器刷新快捷键
  15. 软件版本GA、RC、beta等含义
  16. 如何转换图片格式为png?图片格式如何进行转换?
  17. 百度音频文件转写正式上线商用
  18. 打印菱形图案用java如何做_Java打印出菱形图案
  19. 【Linux C】进程、线程和进程间通信
  20. 【Windows】U 盘装系统,无法格式化所选磁盘分区[错误: 0x8004242d]

热门文章

  1. 《网络安全2022:守望高质量》报告之数据安全热点事件与趋势解读
  2. Unity3D-rigidBody.velocity
  3. 一种使用Python自实现KMeans++聚类算法的写法
  4. 使用技巧-Z平台为第三方系统开放接口过程
  5. EL表达式三目运算符
  6. Flutter:手把手教你进行BLE应用的开发-flutter_blue
  7. 入行数据分析要知道什么是统计
  8. VMware ESXi 8.0集成网卡驱动
  9. 顺序问题,母版页和内容页
  10. 8步文献综述指南——肯特大学(翻译)