Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 5911 Accepted Submission(s): 2064
我们可以逆向认为所有的点全是独立的,因为正
向的时候去掉其中某条边的,独立的点不一定会增多(去掉这条边后还有
其他边间接的相连),所以当我们逆向思考的时候,只会在增加某一条边
时减少独立的点(也就是联通的点增多),这样只会在他之后才会有可能
有某条边的操作是“无效”的(联通的点不变);
#include<iostream> #include<string.h> #include<math.h> #define ll long long using namespace std; ll a[100005], b[100005], c[100005], p[10005]; ll n, m; void init() { for (int i = 0; i < n; i++) p[i] = i; } ll find(ll x) { if (x == p[x]) return x; else return p[x] = find(p[x]); } int main() { while (scanf("%lld%lld", &n, &m) == 2) { init(); for (int i = 1; i <= m; i++) { scanf("%lld%lld", &a[i], &b[i]); } c[m] = n;//m个元素之间都没有连接,此时分成n个集合 for (int i = m; i > 1; i--)//m!=0,所以i!=1 { ll tx, ty; tx = find(a[i]); ty = find(b[i]); if (tx == ty) c[i - 1] = c[i]; else { c[i - 1] = c[i] - 1; p[tx] = ty; } } for (int i = 1; i <= m; i++) { printf("%lld\n", c[i]); } } system("pause"); return 0; }
原文:https://www.cnblogs.com/-citywall123/p/10719924.html