nyoj 925 The troubles of the king (and check out)

King's Troubles

Time Limit: 3000 ms | Memory Limit: 65535 KB
Difficulty: 2
 
describe

    Country C consists of n small islands. In order to facilitate the communication between the small islands, country C has established m bridges between the small islands, and each bridge connects two small islands. There may be multiple bridges connecting the two islands. However, some bridges are in danger of being rendered unusable due to sea wash. If all bridges between the two islands are disabled, the two islands cannot be reached directly. However, as long as the inhabitants of these two small islands can reach each other via other bridges or other small islands, they will be fine. However, if there was a way to reach between the two islands one day, but not the next, the residents would protest together.

    Now the king of country C already knows the number of days that each bridge can be used, and it cannot be used after this number of days. Now he wants to know how many protests the residents will raise altogether.

 
enter
  Multiple sets of test data.
  Enter two positive integers n and m for each set of data first.
  The next m lines, each line contains three integers a, b, t, respectively, indicating that the bridge connects the two islands a and b, and can be used for t days. The number of islands starts from 1 and increases. (1≤n≤10000, 1≤m≤100000, 1<=a, b<=n, 1≤t≤100000)
output
  Output an integer representing the number of times residents protested.
sample input
4 4
1 2 2
1 3 2
2 3 1
3 4 3
Sample output
2
hint
For example:
the bridge between 2 and 3 cannot be used after the first day, no effect.
After the second day, the bridges between 1 and 2, and between 1 and 3 cannot be used, and the residents will protest.
After the third day the bridge between 3 and 4 cannot be used and the residents will protest.
/**
    Analysis: This question is to judge the non-connected area on the i-th day and the non-connected area on the i+1-th day
            If there are more disconnected areas on day i+1 than those on day i: bridge broken, residents protest, cnt++
            
            So we can think backwards <broken bridge<==> bridge repair> (arrange the data in descending order of days):
                If the bridge is not connected to cnt ++ when the two bridges are my_joined <At the same time, consider whether it is the same day as the previous data (because the residents protest at most once a day)>
    Data structure: Union lookup
    template:
        pre [100005];
        void init () {
            for (int i = 1; i <= n; ++ i) {
                pre [i] = i;
            }
            return ;
        }
        
        int my_find (int x) {
            int n = x;
            while (n != pre [n]) {
                n = for [n];
            }
            int i = x, j;
            while (n != pre [i]) {
                j = for [i];
                pre [i] = n;
                i = j;
            }
        }
        
        bool my_join (int a, int b) {
            int n1 = my_find (a), n2 = my_find (b);
            if (n1 != n2) {
                pre [n1] = n2;
                return true;
            } else {
                return false;
            }
        }
**/ 

C/C++ code implementation:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <stack>
#include <queue>
#include <map>

using namespace std;

int n, m, pre [10005];

struct node {
    int x, y, w;
}P [100005];

void init () {
    for (int i = 1; i <= n; ++ i) {
        pre [i] = i;
    }
    return ;
}

bool cmp (node a, node b) {
    return a.w > b.w;
}

int my_find (int x) {
    int n = x;
    while (n != pre [n]) {
        n = for [n];
    }
    int i = x, j;
    while (n != pre [i]) {
        j = for [i];
        pre [i] = n;
        i = j;
    }
    return n;
}

bool my_join (int a, int b) {
    int n1 = my_find (a), n2 = my_find (b);
    if (n1 != n2) {
        pre [n1] = n2;
        return true;
    }
    return false;
}

int main () {
    while (~scanf ("%d%d", &n, &m)) {
        init();
        int cnt = 0, my_first = -1;
        for (int i = 0; i < m; ++ i) {
            scanf ("%d%d%d", &P[i].x, &P[i].y, &P[i].w);
        }
        sort (P, P + m, cmp);
        for (int i = 0; i < m; ++ i) {
            if (my_join (P[i].x, P[i].y) && my_first != P[i].w) {
                ++ cnt;
                my_first = P[i].w; // At most 1 protest per day 
            }
        }
        printf ("%d\n", cnt);
    }
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325169436&siteId=291194637