蓝桥杯历届试题 国王的烦恼(并查集逆序加边+坑)
生活随笔
收集整理的這篇文章主要介紹了
蓝桥杯历届试题 国王的烦恼(并查集逆序加边+坑)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
歷屆試題 國王的煩惱 ? 時間限制:1.0s ? 內存限制:256.0MB 問題描述 C國由n個小島組成,為了方便小島之間聯絡,C國在小島間建立了m座大橋,每座大橋連接兩座小島。兩個小島間可能存在多座橋連接。然而,由于海水沖刷,有一些大橋面臨著不能使用的危險。
如果兩個小島間的所有大橋都不能使用,則這兩座小島就不能直接到達了。然而,只要這兩座小島的居民能通過其他的橋或者其他的小島互相到達,他們就會安然無事。但是,如果前一天兩個小島之間還有方法可以到達,后一天卻不能到達了,居民們就會一起抗議。
現在C國的國王已經知道了每座橋能使用的天數,超過這個天數就不能使用了。現在他想知道居民們會有多少天進行抗議。 輸入格式 輸入的第一行包含兩個整數n, m,分別表示小島的個數和橋的數量。
接下來m行,每行三個整數a, b, t,分別表示該座橋連接a號和b號兩個小島,能使用t天。小島的編號從1開始遞增。 輸出格式 輸出一個整數,表示居民們會抗議的天數。 樣例輸入 4 4
1 2 2
1 3 2
2 3 1
3 4 3 樣例輸出 2 樣例說明 第一天后2和3之間的橋不能使用,不影響。
第二天后1和2之間,以及1和3之間的橋不能使用,居民們會抗議。
第三天后3和4之間的橋不能使用,居民們會抗議。 數據規模和約定 對于30%的數據,1<=n<=20,1<=m<=100;
對于50%的數據,1<=n<=500,1<=m<=10000;
對于100%的數據,1<=n<=10000,1<=m<=100000,1<=a, b<=n, 1<=t<=100000。
如果兩個小島間的所有大橋都不能使用,則這兩座小島就不能直接到達了。然而,只要這兩座小島的居民能通過其他的橋或者其他的小島互相到達,他們就會安然無事。但是,如果前一天兩個小島之間還有方法可以到達,后一天卻不能到達了,居民們就會一起抗議。
現在C國的國王已經知道了每座橋能使用的天數,超過這個天數就不能使用了。現在他想知道居民們會有多少天進行抗議。 輸入格式 輸入的第一行包含兩個整數n, m,分別表示小島的個數和橋的數量。
接下來m行,每行三個整數a, b, t,分別表示該座橋連接a號和b號兩個小島,能使用t天。小島的編號從1開始遞增。 輸出格式 輸出一個整數,表示居民們會抗議的天數。 樣例輸入 4 4
1 2 2
1 3 2
2 3 1
3 4 3 樣例輸出 2 樣例說明 第一天后2和3之間的橋不能使用,不影響。
第二天后1和2之間,以及1和3之間的橋不能使用,居民們會抗議。
第三天后3和4之間的橋不能使用,居民們會抗議。 數據規模和約定 對于30%的數據,1<=n<=20,1<=m<=100;
對于50%的數據,1<=n<=500,1<=m<=10000;
對于100%的數據,1<=n<=10000,1<=m<=100000,1<=a, b<=n, 1<=t<=100000。
?
?
題目鏈接:國王的煩惱
這題很容易想到用逆序的辦法來求連通分支的變化情況,而且顯然對于同一天若出現多個地方的抗議,也只算一次,因為題目要算的是抗議的天數而不是次數,然而抱著1A的心態提交了一發結果只有10分…………,最后發現這里有個坑,假如有兩個邊天數相同,但前面的先被處理且合并失敗,那么后面的雖然合并成功但是跟最后一天的天數相同,因此不會被算到答案里去……,因此只要把更新的語句放到if里面就可以過了
代碼:
#include <stdio.h> #include <bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f #define LC(x) (x<<1) #define RC(x) ((x<<1)+1) #define MID(x,y) ((x+y)>>1) #define CLR(arr,val) memset(arr,val,sizeof(arr)) #define FAST_IO ios::sync_with_stdio(false);cin.tie(0); typedef pair<int, int> pii; typedef long long LL; const double PI = acos(-1.0); const int N = 10010; const int M = 100010; struct info {int a, b, t;bool operator<(const info &rhs)const{return t > rhs.t;} }; info E[M]; int pre[N];void init() {CLR(pre, -1); } int Find(int n) {return pre[n] == -1 ? n : pre[n] = Find(pre[n]); } bool joint(int a, int b) {a = Find(a);b = Find(b);if (a == b)return false;pre[a] = b;return true; } int main(void) {int n, m, i;while (~scanf("%d%d", &n, &m)){init();for (i = 0; i < m; ++i)scanf("%d%d%d", &E[i].a, &E[i].b, &E[i].t);sort(E, E + m);int ans = 0;int last = -1;for (i = 0; i < m; ++i){if (joint(E[i].a, E[i].b) && E[i].t != last){++ans;last = E[i].t;//如果把這句放到括號外,則會出錯,實際上last更準確的來說是維護最后“成功”合并的day}}printf("%d\n", ans);}return 0; }轉載于:https://www.cnblogs.com/Blackops/p/6531211.html
總結
以上是生活随笔為你收集整理的蓝桥杯历届试题 国王的烦恼(并查集逆序加边+坑)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sql判断字段是否为空
- 下一篇: Bzoj 2152: 聪聪可可(点分治)