一、题目链接

  http://acm.hdu.edu.cn/showproblem.php?pid=5222

二、题意

  给一个无向边+有向边的混合图,其中每条边只能使用一次,问图中是否存在环。

三、思路

  1、必备知识点:图中判断是否存在环

  图是否连通都没关系。
  • 无向图
  (1)DFS
  (2)BFS
  (3)并查集
  • 有向图
  (1)拓扑排序
  • 无向边+有向边的混合图
  (1)法1
    ①把所有无向边(u, v)加入到并查集,不加入图中;
    ②对于所有有向边(u, v),在并查集中找出u和v的根结点x和y,图中添加x到y的边(本质就是把并查集中所有的点合并成一个点);
    ③对建立的图做和【有向图】相同的拓扑排序;
    另外,在①和②中,在并查集合并结点u和v的时候,如果u和v已经属于同一个组(祖先相同),那么,说明已经存在环了。
 
   有了上面的知识点,这个题就好做了。直接套一下方法就OK。
  PS:做这个题时,一直纠结如何用一种优雅的方式浓缩并查集中的所有点,思来想去,觉得这个“一边输入,一边浓缩点”的方法,确实是,棒!
四、源代码
#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<set>
#include<vector>
#include<queue>
using namespace std;
#define MAXN 1000100
typedef long long LL;
typedef struct{
    int par[MAXN], rk[MAXN];
    void init(){
        ;i < MAXN;++i)par[i] = i, rk[i] = ;
    }
    int root(int x){
        return x == par[x] ? x : par[x] = root(par[x]);
    }
    void unite(int u, int v){
        int x = root(u), y = root(v);
        if(x == y)return;
        if(rk[x] < rk[y])par[x] = y;
        else{
            par[y] = x;
            if(rk[x] == rk[y])rk[y]++;
        }
    }
    bool same(int u, int v){
        return root(u) == root(v);
    }
}UniFinder;

int N, M1, M2;
vector<int> g[MAXN];
int deg[MAXN];

template<class T> inline void read(T& x){
    char t;
    bool sign = false;
    '));
    if(t == '-')sign = true, t =getchar();
    x = t - ';
     + t - ';
    if(sign)x = -x;
}

priority_queue<int, vector<int>, greater<int> > que;
bool topo_sort(){
    while(!que.empty())que.pop();
    ;i <= N;++i){
        )que.push(i);
    }
    int rest = N;
    while(!que.empty()){
        int top = que.top();
        que.pop();
        rest--;
        , sz = g[top].size();i < sz;++i){
            int to = g[top][i];
            deg[to]--;
            )que.push(to);
        }
    }
    ;
}

UniFinder uf;
int main(){
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    int T, u, v;
    scanf("%d", &T);
    while(T--){
        ;i < MAXN;++i)g[i].clear();
        memset(deg, , sizeof(deg));
        uf.init();
        bool ans = false;
        scanf("%d%d%d", &N, &M1, &M2);
        ;i < M1;++i){
            read(u), read(v);
            if(uf.same(u, v))ans = true;
            uf.unite(u, v);
        }
        ;i < M2;++i){
            read(u), read(v);
            u = uf.root(u), v = uf.root(v);
            if(u == v)ans = true;
            if(ans)continue;
            g[u].push_back(v), deg[v]++;
        }
        if(ans)puts("YES");
        else printf("%s\n", topo_sort() ? "YES" : "NO");
    }
    ;
} 

HDU-5222 Exploration(拓扑排序)的更多相关文章

  1. HDU.2647 Reward(拓扑排序 TopSort)

    HDU.2647 Reward(拓扑排序 TopSort) 题意分析 裸的拓扑排序 详解请移步 算法学习 拓扑排序(TopSort) 这道题有一点变化是要求计算最后的金钱数.最少金钱值是888,最少的 ...

  2. HDU 5222 ——Exploration——————【并查集+拓扑排序判有向环】

    Exploration Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  3. ACM: hdu 2647 Reward -拓扑排序

    hdu 2647 Reward Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Des ...

  4. HDU 2647 Reward (拓扑排序)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2647 题意是给你n点m条有向边,叶子点(出度为0)上的值为888,父亲点为888+1,依次计算... ...

  5. hdu 5438 Ponds 拓扑排序

    Ponds Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/contests/contest_showproblem ...

  6. hdu 4857 逃生 拓扑排序+PQ,剥层分析

    pid=4857">hdu4857 逃生 题目是求拓扑排序,但不是依照字典序最小输出,而是要使较小的数排在最前面. 一開始的错误思路:给每一个点确定一个优先级(该点所能到达的最小的点) ...

  7. HDU 1285 经典拓扑排序入门题

    确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  8. HDU 2647 逆向拓扑排序

    令每一个员工都有一个自己的等级level[i] , 员工等级越高,那么工资越高,为了使发的钱尽可能少,所以每一级只增加一单位的钱 输入a b表示a等级高于b,那么我们反向添加边,令b—>a那么i ...

  9. HDU 4917 Permutation 拓扑排序的计数

    题意: 一个有n个数的排列,给你一些位置上数字的大小关系.求合法的排列有多少种. 思路: 数字的大小关系可以看做是一条有向边,这样以每个位置当点,就可以把整个排列当做一张有向图.而且题目保证有解,所以 ...

随机推荐

  1. 51Nod 1737 配对(树的重心)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1737 题意: 思路: 树的重心. 树的重心就是其所以子树的最大的子树结点 ...

  2. thinkphp3.2笔记(2)调试模式,配置项C,创建模块, 四种URL模式,URL生成,跳转

    一.调试模式 TP的调试模式其实就控制了TP关于配置信息以及函数的缓存功能 如果开启了调试模式,每次访问项目,Tp都会去加载最新的配置以及函数信息. 如果关闭了调试模式,当tp第一次访问时会降配置以及 ...

  3. Linux常用命令--文件操作、权限设置

    1.编辑文件 cat aaa.txt 查看aaa.txt文件的内容 head - aaa.txt 查看aaa.txt文件前5行的内容 tail - aaa.txt 展示aaa.txt文件最后10行的内 ...

  4. Cool Auto-Suggest 插件使用方法

    刚入职的时候公司主管曾经让我用Cool Auto-Suggest 插件写过后台管理页面内的自动填充及搜索功能. 其实这个插件的使用很简单,网上也有相应的翻译文档,但是明显的机翻看着无法忍受.我写一下使 ...

  5. bzoj1211: [HNOI2004]树的计数 prufer序列裸题

    一个有n个结点的树,设它的结点分别为v1, v2, …, vn,已知第i个结点vi的度数为di,问满足这样的条件的不同的树有多少棵.给定n,d1, d2, …, dn,编程需要输出满足d(vi)=di ...

  6. MyBatise代码自动生成时候Oralce的number类型BigDecimal问题

    使用MyBatise的代码自动生成工具时候,即便在配置文件中定义了 <javaTypeResolver> <property name="forceBigDecimals& ...

  7. asp.net中的时间日期选择控件

    asp.net中的时间日期选择控件 Posted on 2008-07-17 17:37 飛雪飄寒 阅读(22922) 评论(6) 编辑 收藏     在系统中经常需要进行时间日期选择(比如查询时间范 ...

  8. zTree简单使用

    zTree使用 zTree github地址 zTree API文档 zTree插件依赖JQ所以使用zTree首先引入JQ,另外zTree的点击功能,编辑功能都是单独的文件,如需使用也要引入(也可以引 ...

  9. CS231n课程笔记翻译8:神经网络笔记 part3

    译者注:本文智能单元首发,译自斯坦福CS231n课程笔记Neural Nets notes 3,课程教师Andrej Karpathy授权翻译.本篇教程由杜客翻译完成,堃堃和巩子嘉进行校对修改.译文含 ...

  10. [QT_OPENCV] qt下opencv配置以及首个opencv工程

    使用环境 : window版本 : win7 x64 QT : 5.8 32bit MinGW530 OpenCv : 3.2 opencv在qt下的环境配置: 在百度上百度了许多关于opencv环境 ...