zoukankan      html  css  js  c++  java
  • 并查集+拓扑排序 赛码 1009 Exploration

    题目传送门

      1 /*
      2     题意:无向图和有向图的混合图判环;
      3 
      4     官方题解:首先对于所有的无向边,我们使用并查集将两边的点并起来,若一条边未合并之前,
      5     两端的点已经处于同一个集合了,那么说明必定存在可行的环(因为这两个点处于同一个并查集集合中,那么它们之间至少存在一条路径)
      6     如果上一步没有判断出环,那么仅靠无向边是找不到环的
      7     考虑到,处于同一个并查集集合中的点之间必定存在一条路径互达,因此将一个集合的点合并之后,
      8     原问题等价于在新生成的有向图中是否有环
      9     我们知道,有向无环图必定存在拓扑序,因此只需使用拓扑排序判定即可
     10     时间复杂度O(N+M1+M2)
     11 
     12     并查集+拓扑排序:并查集来判断无向图,拓扑排序判断有向图
     13     
     14     另外:用读入外挂时间比scanf ()多,不清楚...
     15     Accepted    5222    5007MS    45124K    2158 B    G++    BH        //scanf ()
     16     Accepted    5222    7581MS    45116K    2158 B    G++    BH        //read ()
     17 */
     18 #include <cstdio>
     19 #include <cmath>
     20 #include <cstring>
     21 #include <string>
     22 #include <iostream>
     23 #include <algorithm>
     24 #include <queue>
     25 #include <vector>
     26 #pragma comment(linker, "/STACK:102400000,102400000")
     27 using namespace std;
     28 
     29 const int MAXN = 1e6 + 10;
     30 const int INF = 0x3f3f3f3f;
     31 int ans[MAXN], in[MAXN];
     32 int rt[MAXN];
     33 vector<int> G[MAXN];
     34 int n, m1, m2;
     35 
     36 inline int read(void)
     37 {
     38     int x = 0, f = 1;    char ch = getchar ();
     39     while (ch < '0' || ch > '9')    {if (ch == '-')    f = -1;    ch = getchar ();}
     40     while (ch >= '0' && ch <= '9')    {x = x * 10 + ch - '0';    ch = getchar ();}
     41     return x * f;
     42 }
     43 
     44 bool TopoSort(void)
     45 {
     46     memset (in, 0, sizeof (in));
     47     for (int i=1; i<=n; ++i)
     48         for (int j=0; j<G[i].size (); ++j)    in[G[i][j]]++;
     49 
     50     queue<int> Q;    int cnt = 0;
     51     for (int i=1; i<=n; ++i)    {if (!in[i]) Q.push (i);}
     52 
     53     while (!Q.empty ())
     54     {
     55         int u = Q.front ();    Q.pop ();
     56         ans[++cnt] = u;
     57         for (int j=0; j<G[u].size (); ++j)
     58         {
     59             int v = G[u][j];
     60             in[v]--;
     61             if (!in[v])    Q.push (v);
     62         }
     63     }
     64 
     65     if (cnt == n)    return false;
     66     else return true;
     67 }
     68 
     69 int Find(int x)
     70 {
     71     return (rt[x] == x) ? rt[x] : rt[x] = Find (rt[x]);
     72 }
     73 
     74 void Union(int x, int y)
     75 {
     76     x = Find (x);    y = Find (y);
     77     if (x < y)    rt[x] = y;
     78     else    rt[y] = x;
     79 }
     80 
     81 bool same(int x, int y)
     82 {
     83     return (Find (x) == Find (y)) ? true : false;
     84 }
     85 
     86 int main(void)        //赛码 1009 Exploration
     87 {
     88     //freopen ("I.in", "r", stdin);
     89 
     90     int t;
     91     scanf ("%d", &t);
     92     while (t--)
     93     {
     94         scanf ("%d%d%d", &n, &m1, &m2);
     95 
     96         for (int i=1; i<=n; ++i)    rt[i] = i;
     97         for (int i=1; i<=n; ++i)    G[i].clear ();
     98 
     99         bool ok = false;    int u, v;
    100         for (int i=1; i<=m1; ++i)
    101         {    
    102             scanf ("%d%d", &u, &v);
    103             //u = read ();    v = read ();
    104             //G[u].push_back (v);
    105             if (same (u, v) == true)    ok = true;
    106             else    Union (u, v);
    107         }
    108         for (int i=1; i<=m2; ++i)
    109         {
    110             int u, v;
    111             scanf ("%d%d", &u, &v);
    112             //u = read ();    v = read ();
    113             if (same (u, v) == true)    ok = true;
    114             if (ok)    continue;
    115             G[u].push_back (v);
    116         }
    117 
    118         if (ok)        {puts ("YES");    continue;}
    119         if (TopoSort () == true)    puts ("YES");
    120         else    puts ("NO");
    121     }
    122 
    123     return 0;
    124 }
    编译人生,运行世界!
  • 相关阅读:
    JavaScript cookie详解
    Javascript数组的排序:sort()方法和reverse()方法
    javascript中write( ) 和 writeln( )的区别
    div做表格
    JS 盒模型 scrollLeft, scrollWidth, clientWidth, offsetWidth 详解
    Job for phpfpm.service failed because the control process exited with error code. See "systemctl status phpfpm.service" and "journalctl xe" for details.
    orm查询存在价格为空问题
    利用救援模式破解系统密码
    SSH服务拒绝了密码
    C# 调用 C++ DLL 中的委托,引发“对XXX::Invoke类型的已垃圾回收委托进行了回调”错误的解决办法
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4475659.html
Copyright © 2011-2022 走看看