zoukankan      html  css  js  c++  java
  • zstu.4191: 无向图找环(dfs树 + 邻接表)

    4191: 无向图找环

    Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 117  Solved: 34

    Description

     给你一副无向图,每条边有边权,保证图联通,现在让你判断这个图是否有异或值大于零的环存在。

     

    Input

     多组测试数据,每组先输入两个数n m,表示图的点跟边的数量。

    然后是m行,每行三个数a b c。代表一条边的起点,终点,边权。

    1 <= n<= 100000, 1 <= m <= 200000.

    1 <= a <= n, 1 <= b <= n, a != b.

    0 <= c <= 32767

    Output

     对于每组数据输出Yes或者 No。

    Sample Input

    3 3
    1 2 0
    2 3 1
    3 1 1
    

    Sample Output

    No

    HINT

     

    Source

    Wuyiqi

     1 #include<cstdio>
     2 #include<map>
     3 using namespace std;
     4 const int N = 100000 + 10 , M =  200000 + 10 ;
     5 struct edge
     6 {
     7     int u , v , nxt ;
     8     int w ;
     9 }e[M * 2];
    10 int head[M * 2] , E = 0 ;
    11 bool vis [N] ;
    12 int sumxor[N] ;
    13 int n , m ;
    14 int u , v , w ;
    15 bool flag ;
    16 
    17 void add (int u , int v , int w)
    18 {
    19     e[E].u = u , e[E].v = v , e[E].w = w , e[E].nxt = head[u] ;
    20     head[u] = E ++ ;
    21     e[E].u = v , e[E].v = u , e[E].w = w , e[E].nxt = head[v] ;
    22     head[v] = E ++ ;
    23 }
    24 
    25 void dfs (int u)
    26 {
    27     for (int i = head[u] ; i != -1 ; i = e[i].nxt) {
    28         if (! vis[e[i].v]) {
    29             vis[e[i].v] = 1 ;
    30             sumxor[e[i].v] = sumxor[u] ^ e[i].w ;
    31             dfs (e[i].v) ;
    32         }
    33         else {
    34             if ( (sumxor[e[i].v] ^ sumxor[u] ^ e[i].w) ) {
    35                 flag = 1 ;
    36                 return ;
    37             }
    38         }
    39     }
    40 }
    41 
    42 int main ()
    43 {
    44     //freopen ("a.txt" , "r" , stdin ) ;
    45     while (~ scanf ("%d%d" , &n , &m) ) {
    46         E = 0 ;
    47         flag = 0 ;
    48         fill (head , head + n + 1 , -1 ) ;
    49         while (m --) {
    50             scanf ("%d%d%d" , &u , &v , &w) ;
    51             add (u , v , w) ;
    52         }
    53         fill (vis , vis + n + 1 , 0) ;
    54         vis[1] = 1 ;
    55         sumxor[1] = 0 ;
    56         dfs (1) ;
    57         printf ("%s
    " , flag ? "Yes" : "No" ) ;
    58     }
    59     return 0 ;
    60 }
    View Code

    dfs树:
    只要在ADG中进行广搜,只要有祖先和对应节点这种关系,那么他们就能构成环;反之若 任意 一对节点不符合这个原则,就不能构成环。(简单来说你能搜到就能成环)

    此外nxt 存放的是 “边”。

    因为用dfs找点只需 n 次 , 而用了邻接表找边 只需 m 次。

    又因为如果两个小环的异或值!= 0 , 那么所形成的的大环的异或值肯定 != 0 ;

    所以总的复杂度为O(n + m)。

  • 相关阅读:
    HDU 1022 Train Problem I
    HDU 1702 ACboy needs your help again!
    HDU 1294 Rooted Trees Problem
    HDU 1027 Ignatius and the Princess II
    HDU 3398 String
    HDU 1709 The Balance
    HDU 2152 Fruit
    HDU 1398 Square Coins
    HDU 3571 N-dimensional Sphere
    HDU 2451 Simple Addition Expression
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4386636.html
Copyright © 2011-2022 走看看