zoukankan      html  css  js  c++  java
  • POJ 3352 Road Construction

    嘟嘟嘟

    总的来说,就是求最少加几条边,使图成为一个边双连通图。

    显然先边双连通分量缩点,于是图就变成了一棵树(因为是无向图),然后我就在纸上画了半天,得到了一个结论:只要连叶子节点数 / 2(向上取整)条边,这颗树就成了一个边双连通图。

    就是叶子之间两两连边,然后如果是奇数个叶子节点,就把多的那个向根节点连一条边。而且奇特的是,并不是所有连边方案都可行,但却一定有至少一种方案可以。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<cctype>
      8 #include<vector>
      9 #include<stack>
     10 #include<queue>
     11 using namespace std;
     12 #define enter puts("") 
     13 #define space putchar(' ')
     14 #define Mem(a, x) memset(a, x, sizeof(a))
     15 #define rg register
     16 typedef long long ll;
     17 typedef double db;
     18 const int INF = 0x3f3f3f3f;
     19 const db eps = 1e-8;
     20 const int maxn = 1e3 + 5;
     21 inline ll read()
     22 {
     23     ll ans = 0;
     24     char ch = getchar(), last = ' ';
     25     while(!isdigit(ch)) {last = ch; ch = getchar();}
     26     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
     27     if(last == '-') ans = -ans;
     28     return ans;
     29 }
     30 inline void write(ll x)
     31 {
     32     if(x < 0) x = -x, putchar('-');
     33     if(x >= 10) write(x / 10);
     34     putchar(x % 10 + '0');
     35 }
     36 
     37 int n, m;
     38 vector<int> v[maxn];
     39 
     40 stack<int> st;
     41 bool in[maxn];
     42 int dfn[maxn], low[maxn], cnt = 0;
     43 int col[maxn], ccol = 0;
     44 void tarjan(int now, int fa)
     45 {
     46     dfn[now] = low[now] = ++cnt;
     47     st.push(now); in[now] = 1;
     48     for(int i = 0; i < (int)v[now].size(); ++i)
     49     {
     50         if(!dfn[v[now][i]])
     51         {
     52             tarjan(v[now][i], now);
     53             low[now] = min(low[now], low[v[now][i]]);
     54         }
     55         else if(v[now][i] != fa) low[now] = min(low[now], dfn[v[now][i]]);
     56             //第一次知道这还得有个判断 
     57     }
     58     if(dfn[now] == low[now])
     59     {
     60         int x; ++ccol;
     61         do
     62         {
     63             x = st.top(); st.pop();
     64             in[x] = 0;
     65             col[x] = ccol;
     66         }while(x != now);    
     67     }
     68 }
     69 
     70 int Cnt = 0;
     71 vector<int> v2[maxn];
     72 int to[maxn];
     73 void newGraph(int now)
     74 {
     75     int u = col[now];
     76     for(int i = 0; i < (int)v[now].size(); ++i)
     77     {
     78         int e = col[v[now][i]];
     79         if(u == e) continue;
     80         v2[u].push_back(e); v2[e].push_back(u);
     81     }
     82 }
     83 
     84 int solve(int now)            //判断度为 1 的点,就是叶子节点 
     85 {
     86     int pos = 0, flg = -1;    //flg : -1代表无出边,0为一条,大于1为一条以上 
     87     for(int i = 0; i < (int)v2[now].size(); ++i)
     88     {
     89         if(flg == -1) pos = v2[now][i], flg = 0;
     90         if(pos != v2[now][i]) flg++;
     91     }
     92     return flg == 0;
     93 }
     94 
     95 int main()
     96 {
     97     n = read(); m = read();
     98     for(int i = 1; i <= m; ++i)
     99     {
    100         int x = read(), y = read();
    101         v[x].push_back(y); v[y].push_back(x);
    102     }
    103     for(int i = 1; i <= n; ++i) if(!dfn[i]) tarjan(i, 0);
    104     for(int i = 1; i <= n; ++i) newGraph(i);
    105     for(int i = 1; i <= ccol; ++i) Cnt += solve(i);
    106     write((Cnt + 1) >> 1); enter;
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    软件需求与分析课堂讨论一
    架构漫谈读后感
    Android Studio AVD中文输入法安装
    软件体系结构课后作业01
    寒假阅读笔记六
    寒假阅读笔记五
    寒假阅读笔记三
    寒假阅读笔记二
    寒假阅读笔记一
    mysql绿色版的安装
  • 原文地址:https://www.cnblogs.com/mrclr/p/9669524.html
Copyright © 2011-2022 走看看