zoukankan      html  css  js  c++  java
  • hdu 5438 拓扑排序+并查集

    remove的过程就像是拓扑排序,而最后统计sum可以用并查集,每个集合维护集合的size、sum。

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <cstring>
      4 #include <cstdio>
      5 #include <queue>
      6 using namespace std;
      7 
      8 typedef long long ll;
      9 const int INF = 999999999;
     10 const int N = 20000;
     11 const int M = 200000;
     12 int f[N];
     13 int sz[N];
     14 ll sum[N];
     15 int in[N];
     16 int head[N];
     17 queue<int> q;
     18 int n, m, e;
     19 
     20 struct Edge
     21 {
     22     int v, next;
     23 } edge[M << 1];
     24 
     25 void addEdge( int u, int v )
     26 {
     27     edge[e].v = v;
     28     edge[e].next = head[u];
     29     head[u] = e++;
     30 }
     31 
     32 void init()
     33 {
     34     while ( !q.empty() ) q.pop();
     35     e = 0;
     36     memset( in, 0, sizeof(in) );
     37     memset( head, -1, sizeof(head) );
     38     for ( int i = 1; i <= n; i++ )
     39     {
     40         f[i] = i;
     41         sz[i] = 1;
     42     }
     43 }
     44 
     45 int findf( int x )
     46 {
     47     if ( f[x] != x ) f[x] = findf( f[x] );
     48     return f[x];
     49 }
     50 
     51 void union_set( int x, int y )
     52 {
     53     x = findf(x), y = findf(y);
     54     if ( x != y )
     55     {
     56         f[x] = y;
     57         sz[y] += sz[x];
     58         sum[y] += sum[x];
     59     }
     60 }
     61 
     62 int main ()
     63 {
     64     int t;
     65     scanf("%d", &t);
     66     while ( t-- )
     67     {
     68         scanf("%d%d", &n, &m);
     69         init();
     70         for ( int i = 1; i <= n; i++ )
     71         {
     72             scanf("%I64d", &sum[i]);
     73         }
     74         while ( m-- )
     75         {
     76             int u, v;
     77             scanf("%d%d", &u, &v);
     78             in[u]++;
     79             in[v]++;
     80             addEdge( u, v );
     81             addEdge( v, u );
     82         }
     83         for ( int i = 1; i <= n; i++ )
     84         {
     85             if ( in[i] < 2 )
     86             {
     87                 q.push(i);
     88                 in[i] = INF;
     89             }
     90         }
     91         while ( !q.empty() )
     92         {
     93             int u = q.front();
     94             q.pop();
     95             for ( int i = head[u]; i != -1; i = edge[i].next )
     96             {
     97                 int v = edge[i].v;
     98                 in[v]--;
     99                 if ( in[v] < 2 )
    100                 {
    101                     q.push(v);
    102                     in[v] = INF;
    103                 }
    104             }
    105         }
    106         for ( int i = 1; i <= n; i++ )
    107         {
    108             if ( in[i] > n ) continue;
    109             for ( int j = head[i]; j != -1; j = edge[j].next )
    110             {
    111                 int v = edge[j].v;
    112                 if ( in[v] > n ) continue;
    113                 union_set( i, v );
    114             }
    115         }
    116         ll ans = 0;
    117         for ( int i = 1; i <= n; i++ )
    118         {
    119             if ( in[i] < n && f[i] == i && sz[i] % 2 == 1 )
    120             {
    121                 ans += sum[i];
    122             }
    123         }
    124         printf("%I64d
    ", ans);
    125     }
    126     return 0;
    127 }
  • 相关阅读:
    【转】软链接和硬链接到底有啥作用和区别
    useradd命令详解
    【转】Linux下MySQL数据库安装及配置方法
    【转】MySQL的安装与配置——详细教程-window系统下
    mysql服务器常用命令
    【转】DDL/DML/DCL区别概述
    tmux终端工具的简单使用
    linux go环境安装和基本项目结构
    ClickHouse高可用集群的配置
    centos7下使用rpm包安装clickhouse
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4806330.html
Copyright © 2011-2022 走看看