zoukankan      html  css  js  c++  java
  • hdu-4738.Caocao's Bridges(图中权值最小的桥)

    Caocao's Bridges

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 10933    Accepted Submission(s): 3065


    Problem Description
    Caocao was defeated by Zhuge Liang and Zhou Yu in the battle of Chibi. But he wouldn't give up. Caocao's army still was not good at water battles, so he came up with another idea. He built many islands in the Changjiang river, and based on those islands, Caocao's army could easily attack Zhou Yu's troop. Caocao also built bridges connecting islands. If all islands were connected by bridges, Caocao's army could be deployed very conveniently among those islands. Zhou Yu couldn't stand with that, so he wanted to destroy some Caocao's bridges so one or more islands would be seperated from other islands. But Zhou Yu had only one bomb which was left by Zhuge Liang, so he could only destroy one bridge. Zhou Yu must send someone carrying the bomb to destroy the bridge. There might be guards on bridges. The soldier number of the bombing team couldn't be less than the guard number of a bridge, or the mission would fail. Please figure out as least how many soldiers Zhou Yu have to sent to complete the island seperating mission.
     
    Input
    There are no more than 12 test cases.

    In each test case:

    The first line contains two integers, N and M, meaning that there are N islands and M bridges. All the islands are numbered from 1 to N. ( 2 <= N <= 1000, 0 < M <= N2 )

    Next M lines describes M bridges. Each line contains three integers U,V and W, meaning that there is a bridge connecting island U and island V, and there are W guards on that bridge. ( U ≠ V and 0 <= W <= 10,000 )

    The input ends with N = 0 and M = 0.
     
    Output
    For each test case, print the minimum soldier number Zhou Yu had to send to complete the mission. If Zhou Yu couldn't succeed any way, print -1 instead.
     
    Sample Input
    3 3 1 2 7 2 3 4 3 1 4 3 2 1 2 7 2 3 4 0 0
     
    Sample Output
    -1 4
     
    Source
     
    Recommend
    liuyiding
     
     
    下面的代码是使用并查集判环,实际上只需要在每次进行tarjan算法时给计数器加一,就知道有几个连通块了,在哪加我标出来了
      1 /*************************************************************************
      2     > File Name: hdu-4738.caocaos_bridges.cpp
      3     > Author: CruelKing
      4     > Mail: 2016586625@qq.com 
      5     > Created Time: 2019年09月07日 星期六 21时41分41秒
      6     本题思路:无向图所有桥中权值的那条桥的权值.
      7     注意:有重边,如果桥上没敌人,需要有人抗tnt,因此需要输出1.
      8     如果初始图不连通则输出0.
      9  ************************************************************************/
     10 
     11 #include <cstdio>
     12 #include <cstring>
     13 #include <map>
     14 using namespace std;
     15 
     16 const int maxn = 1000 + 5, maxm = maxn * maxn + 5, inf = 0x3f3f3f3f;
     17 int n, m;
     18 int tot, head[maxn];
     19 
     20 int bridge, top, Index, min_bridge;
     21 int dfn[maxn], low[maxn], stack[maxn];
     22 bool instack[maxn];
     23 
     24 map<int, int> mp;
     25 
     26 struct Edge {
     27     int to, cost, next;
     28     bool cut;
     29 } edge[maxm << 1];
     30 
     31 int min(int x, int y) {
     32     return x > y ? y : x;
     33 }
     34 
     35 void init() {
     36     mp.clear();
     37     memset(head, -1, sizeof head);
     38     tot = 0;
     39 }
     40 
     41 void addedge(int u, int v ,int w) {
     42     edge[tot] = (Edge){v, w, head[u], false}; head[u] = tot ++;
     43     edge[tot] = (Edge){u, w, head[v], false}; head[v] = tot ++;
     44 }
     45 
     46 bool ishash(int u, int v) {
     47     return mp[u * maxn + v] ++ || mp[v * maxn + u] ++;
     48 }
     49 
     50 void tarjan(int u, int pre) {
     51     int v;
     52     stack[top ++] = u;
     53     instack[u] = true;
     54     dfn[u] = low[u] = ++ Index;
     55     int pre_cnt = 0;
     56     for(int i = head[u]; ~i; i = edge[i].next) {
     57         v = edge[i].to;
     58         if(v == pre && pre_cnt == 0) {
     59             pre_cnt ++;
     60             continue;
     61         }
     62         if(!dfn[v]) {
     63             tarjan(v, u);
     64             if(low[u] > low[v]) low[u] = low[v];
     65             if(low[v] > dfn[u]) {
     66                 edge[i].cut = true;
     67                 edge[i ^ 1].cut = true;
     68                 min_bridge = min(min_bridge, edge[i].cost);
     69                 bridge ++;
     70             }
     71         } else if(low[u] > dfn[v]) low[u] = dfn[v];
     72     }
     73     top --;
     74     instack[u] = false;
     75 }
     76 
     77 void solve() {
     78     memset(instack, false, sizeof instack);
     79     memset(dfn, 0, sizeof dfn);
     80     memset(low, 0, sizeof low);
     81     top = Index = bridge = 0;
     82     min_bridge = inf;
     83     for(int i = 1; i <= n; i ++) {
     84         if(!dfn[i]) {
     85             tarjan(i, i);//cnt ++;
     86         }
     87     }
     88     if(min_bridge == inf) min_bridge = -1;
     89     else if(min_bridge == 0) min_bridge = 1;//if cnt != 1 : min_bridge = 0;
     90     printf("%d
    ", min_bridge);
     91 }
     92 
     93 int fa[maxn];
     94 
     95 int find(int x) {
     96     if(fa[x] != x) return fa[x] = find(fa[x]);
     97     else return x;
     98 }
     99 
    100 void unionset(int u, int v) {
    101     u = find(u);
    102     v = find(v);
    103     if(u != v) fa[u] = v;
    104 }
    105 
    106 int main() {
    107     int u, v, w;
    108     while(~scanf("%d %d", &n, &m) && (n || m)) {
    109         init();
    110         for(int i = 1; i <= n; i ++) fa[i] = i;
    111         for(int i = 0; i < m; i ++) {
    112             scanf("%d %d %d", &u, &v, &w);
    113 //            if(ishash(u, v)) continue;
    114             addedge(u, v, w);
    115             unionset(u, v);
    116         }
    117         bool flag = true;
    118         for(int i = 1; i <= n; i ++)
    119             if(find(i) != find(1)) {
    120                 flag = false;
    121                 break;
    122             }
    123         if(flag)
    124             solve();
    125         else printf("0
    ");
    126     }
    127     return 0;
    128 }
  • 相关阅读:
    Maven项目多环境之间的配置文件的切换
    使用vue脚手架快速创建vue项目(入门)
    SpringAOP之使用切入点创建通知
    epoll的陷阱
    epoll-1
    openSUSE Leap 15格式化挂载新分区
    openSUSE Leap 15取消自动登录
    openSUSE Leap 15通过windows rdp访问
    openSUSE Leap 15安装打开ssh
    数组、函数与指针
  • 原文地址:https://www.cnblogs.com/bianjunting/p/11483825.html
Copyright © 2011-2022 走看看