zoukankan      html  css  js  c++  java
  • HDU 2242 双连通分量 考研路茫茫——空调教室

    思路就是求边双连通分量,然后缩点,再用树形DP搞一下。

    代码和求强连通很类似,有点神奇,=_=,慢慢消化吧

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <vector>
      5 #include <stack>
      6 using namespace std;
      7 
      8 const int maxn = 10000 + 10;
      9 const int maxm = 20000 + 10;
     10 
     11 int n, m;
     12 int a[maxn];
     13 
     14 struct Edge
     15 {
     16     int v, nxt;
     17 }edges[maxm * 2];
     18 int ecnt;
     19 int head[maxn];
     20 
     21 bool vis[maxn];
     22 
     23 void AddEdge(int u, int v)
     24 {
     25     edges[ecnt].v = v;
     26     edges[ecnt].nxt = head[u];
     27     head[u] = ecnt++;
     28 }
     29 
     30 stack<int> S;
     31 int dfs_clock, scc_cnt;
     32 int low[maxn], pre[maxn], sccno[maxn], w[maxn];
     33 
     34 void dfs(int u, int fa)
     35 {
     36     low[u] = pre[u] = ++dfs_clock;
     37     S.push(u);
     38 
     39     for(int i = head[u]; ~i; i = edges[i].nxt)
     40     {
     41         if(i == (fa ^ 1)) continue;
     42         int v = edges[i].v;
     43         if(!pre[v])
     44         {
     45             dfs(v, i);
     46             low[u] = min(low[u], low[v]);
     47         }
     48         else if(!sccno[v]) low[u] = min(low[u], pre[v]);
     49     }
     50 
     51     if(pre[u] == low[u])
     52     {
     53         scc_cnt++;
     54         for(;;)
     55         {
     56             int x = S.top(); S.pop();
     57             sccno[x] = scc_cnt;
     58             w[scc_cnt] += a[x];
     59             if(x == u) break;
     60         }
     61     }
     62 }
     63 
     64 void find_scc()
     65 {
     66     scc_cnt = dfs_clock = 0;
     67     memset(w, 0, sizeof(w));
     68     memset(pre, 0, sizeof(pre));
     69     memset(sccno, 0, sizeof(sccno));
     70     for(int i = 0; i < n; i++) if(!pre[i]) dfs(i, -1);
     71 }
     72 
     73 vector<int> G[maxn];
     74 
     75 void dfs2(int u)
     76 {
     77     vis[u] = true;
     78     for(int i = 0; i < G[u].size(); i++)
     79     {
     80         int v = G[u][i];
     81         if(vis[v]) continue;
     82         dfs2(v);
     83         w[u] += w[v];
     84     }
     85 }
     86 
     87 int main()
     88 {
     89     while(scanf("%d%d", &n, &m) == 2 && n)
     90     {
     91         int sum = 0;
     92         for(int i = 0; i < n; i++) { scanf("%d", a + i); sum += a[i]; }
     93 
     94         memset(head, -1, sizeof(head));
     95         ecnt = 0;
     96 
     97         while(m--)
     98         {
     99             int u, v; scanf("%d%d", &u, &v);
    100             AddEdge(u, v); AddEdge(v, u);
    101         }
    102 
    103         find_scc();
    104 
    105         if(scc_cnt == 1) { puts("impossible"); continue; }
    106 
    107         for(int i = 1; i <= scc_cnt; i++) G[i].clear();
    108         for(int u = 0; u < n; u++)
    109             for(int i = head[u]; ~i; i = edges[i].nxt)
    110             {
    111                 int v = edges[i].v;
    112                 if(sccno[u] != sccno[v]) G[sccno[u]].push_back(sccno[v]);
    113             }
    114 
    115         memset(vis, false, sizeof(vis));
    116         dfs2(1);
    117 
    118         int ans = 1000000000;
    119         for(int i = 1; i <= scc_cnt; i++) ans = min(ans, abs(sum - w[i] * 2));
    120         printf("%d
    ", ans);
    121     }
    122 
    123     return 0;
    124 }
    代码君
  • 相关阅读:
    原创js脚本实现百度网盘任意文件强制下载
    百度网盘大文件直接下载与下载提速的简单方法
    MVP架构的一个小例子
    PCQQ
    WPF
    百度网盘的限速破解
    何德何能?
    Maven多模块+SpringBoot 编译失败:程序包xxx不存在
    将Spring Boot项目部署到阿里云服务器上(二、安装MySQL服务器)
    将Spring Boot项目部署到阿里云服务器上(一、安装JDK)
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4721540.html
Copyright © 2011-2022 走看看