题目链接:https://ac.nowcoder.com/acm/problem/20566?&headNav=acm
题意:给n个装备,每个装备有两个属性,并且最多只能使用一次。求由这些点的属性能最大匹配到的值。
思路:把每个属性看成点,每个装备看成边。然后连接成k个连通块,如果该连通块为树状,则答案只能是k-1;如果连通块为环状,则答案为k。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| #include<bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN=1e6+5; const int MOD=1e8+7;
int vis[MAXN]; int fa[MAXN]; int n; int fun(int x) { return fa[x]==x ? x : fa[x]=fun(fa[x]); }
void unite(int x,int y) { int a=fun(x); int b=fun(y); if(a==b) { vis[a]=1; return ; } if(a>b) swap(a,b); vis[a]=1; fa[a]=b; }
int main() { scanf("%d",&n); for(int i=1;i<=1000000;i++) fa[i]=i; for(int i=1;i<=n;i++) { int a,b; scanf("%d%d",&a,&b); unite(a,b); } for(int i=1;i<=n;i++) {
if(!vis[i]) { printf("%d\n",i-1); break; }
if(i==n&&vis[i]) {
printf("%d\n",i); } } return 0; }
|