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 }
  • 相关阅读:
    实验四(作业一:字符串加密)
    实验三“类和对象”动手动脑
    实验三“类和对象”课后作业(追踪已经创建了几个对象)
    递归实验动手动脑题目
    ("X+Y="+X+Y)与(X+Y+"=X+Y")
    Linq To Xml
    代码优先-Code First
    restFul接口设计规范
    四: 使用vue搭建网站前端页面
    三: vue组件开发及自动化工具vue-cli
  • 原文地址:https://www.cnblogs.com/bianjunting/p/11483825.html
Copyright © 2011-2022 走看看