zoukankan      html  css  js  c++  java
  • 桥的题目列表

    桥:

    定义:删除一条边,使得原图的连通分量增加的,即为桥。

    一般容易出现的trick

    ①重边

    ②多个图

    题目列表

    ①UVA 796 模板题(一)

    ②HDU4738 重边+许多坑点(二)

    一:UVA796 

    题目大意:给你一个图,问有几个桥?先输入u,在输入(cnt)个和他连接的边

    思路:模板题,不多说了。

     1 //看看会不会爆int!数组会不会少了一维!
     2 //取物问题一定要小心先手胜利的条件
     3 #include <bits/stdc++.h>
     4 using namespace std;
     5 #define LL long long
     6 #define ALL(a) a.begin(), a.end()
     7 #define pb push_back
     8 #define mk make_pair
     9 #define fi first
    10 #define se second
    11 const int maxn = 1000 + 5;
    12 vector<int> G[maxn];
    13 vector<pair<int, int> > ans;
    14 int pre[maxn], low[maxn];
    15 int n, dfstime;
    16 
    17 int dfs(int u, int fa){
    18     int lowu = pre[u] = ++dfstime;
    19     int child = 0;
    20     int len = G[u].size();
    21     for (int i = 0; i < len; i++){
    22         int v = G[u][i];
    23         if (!pre[v]){
    24             child++;
    25             int lowv = dfs(v, u);
    26             lowu = min(lowv, lowu);
    27             if (lowv > pre[u]){
    28                 ans.pb(mk(u, v));
    29             }
    30         }
    31         else if (pre[v] < pre[u] && v != fa){
    32             lowu = min(lowu, pre[v]);
    33         }
    34     }
    35     return lowu;
    36 }
    37 
    38 int main(){
    39     while (scanf("%d", &n) == 1){
    40         for (int i = 1; i <= n; i++){
    41             G[i].clear();
    42             pre[i] = 0;
    43         }
    44         for (int i = 1; i <= n; i++){
    45             int u, v, cnt;
    46             scanf("%d (%d)", &u, &cnt); u++;
    47             for (int j = 1; j <= cnt; j++){
    48                 scanf("%d", &v); v++;
    49                 G[u].pb(v); G[v].pb(u);
    50             }
    51         }
    52         dfstime = 0;
    53         for (int i = 1; i <= n; i++){
    54             if (!pre[i]){
    55                 dfs(i, -1);
    56             }
    57         }
    58         int len = ans.size();
    59         for (int i = 0; i < len; i++)
    60             if (ans[i].fi > ans[i].se) swap(ans[i].fi, ans[i].se);
    61         sort(ALL(ans));
    62         printf("%d critical links
    ", len);
    63         for (int i = 0; i < len; i++){
    64             printf("%d - %d
    ", ans[i].first - 1, ans[i].second - 1);
    65         }
    66         printf("
    ");
    67         ans.clear();
    68     }
    69     return 0;
    70 }
    View Code

    二:HDU4738

    题目大意:周瑜炸桥,给你一个图,每个顶点之间都有一条边,边上都有val个人把手,如何炸桥能使得这个图不连通。炸桥所需要的人数必须是>=val的人数的,问最少需要几个人?

    思路:找出所有的桥,然后枚举一下val即可。

    这里有好多个trick

    ①图可能本来就不连通的

    ②如果该桥的val是0的话,也至少要派一个人过去。

    ③可能有重边(重边的val定义成inf即可)

    由于。。。我把ans.clear()放在最后面了,结果卡了我1h的WA,

    教训:人的数目,初始化的位置

     1 //看看会不会爆int!数组会不会少了一维!
     2 //取物问题一定要小心先手胜利的条件
     3 #include <bits/stdc++.h>
     4 using namespace std;
     5 #define LL long long
     6 #define ALL(a) a.begin(), a.end()
     7 #define pb push_back
     8 #define mk make_pair
     9 #define fi first
    10 #define se second
    11 const int maxn = 1000 + 5;
    12 const int inf = 0x3f3f3f3f;
    13 vector<int> G[maxn];
    14 vector<pair<int, int> > ans;
    15 int a[maxn][maxn];
    16 int pre[maxn], low[maxn];
    17 int n, p, dfstime;
    18 
    19 int dfs(int u, int fa){
    20     int lowu = pre[u] = ++dfstime;
    21     int child = 0;
    22     int len = G[u].size();
    23     for (int i = 0; i < len; i++){
    24         int v = G[u][i];
    25         if (!pre[v]){
    26             child++;
    27             int lowv = dfs(v, u);
    28             lowu = min(lowv, lowu);
    29             if (lowv > pre[u] && a[u][v] != inf){
    30                 ans.pb(mk(u, v));
    31             }
    32         }
    33         else if (pre[v] < pre[u] && v != fa){
    34             lowu = min(lowu, pre[v]);
    35         }
    36     }
    37     return lowu;
    38 }
    39 
    40 int main(){
    41     while (scanf("%d%d", &n, &p) == 2 && n + p){
    42         for (int i = 1; i <= n; i++){
    43             G[i].clear();
    44             pre[i] = 0;
    45         }
    46         ans.clear();
    47         memset(a, -1, sizeof(a));
    48         for (int i = 1; i <= p; i++){
    49             int u, v, cnt;
    50             scanf("%d %d %d", &u, &v, &cnt);
    51             G[u].pb(v); G[v].pb(u);
    52             if (a[u][v] != -1){
    53                 a[v][u] = a[u][v] = inf;
    54                 continue;
    55             }
    56             a[u][v] = a[v][u] = cnt;
    57         }
    58         dfstime = 0;
    59         int cnt = 0;
    60         for (int i = 1; i <= n; i++){
    61             if (!pre[i]){
    62                 cnt++;
    63                 dfs(i, -1);
    64             }
    65         }
    66         if (cnt > 1){
    67             printf("0
    "); continue;
    68         }
    69         int len = ans.size();
    70         int res = 0x3f3f3f3f;
    71         for (int i = 0; i < len; i++){
    72             res = min(res, a[ans[i].fi][ans[i].se]);
    73         }
    74         ///①0个人的桥也需要一个人去炸②一开始可能就不连通
    75         if (res == 0 && len != 0) res += 1;
    76         if (len == 0) res = -1;
    77         printf("%d
    ", res);
    78     }
    79     return 0;
    80 }
    View Code

    三:

    四:

    五:

    六:

  • 相关阅读:
    31. Ubuntu15.04系统中如何启用、禁用客人会话
    dpkg安装deb缺少依赖包的解决方法
    C语言宏中"#"和"##"的用法
    编译android6.0错误recipe for target 'out/host/linux-x86/obj/lib/libart.so' failed
    Android api level对照表
    Android 如何判断CPU是32位还是64位
    vim map nmap(转)
    vim配置及插件安装管理(超级详细)
    Java多线程总结(二)锁、线程池
    Python快速教程目录(转)
  • 原文地址:https://www.cnblogs.com/heimao5027/p/5805712.html
Copyright © 2011-2022 走看看