[bzoj1854]游戏

考虑将武器(a,b)看成一条无向边,那么对于一个连通块
1.当没有环,即是一棵树,那么任选一个点作为根,每条边只选儿子节点即可,显然根要选编号最大的
2.当有环,任选一个环作为根,其余环上的某一条边拆掉使得变成基环树,树边选择儿子,环边按某种顺序选择即可
那么题目相当于要求维护每一个树连通块的最小的最大编号,用并查集维护即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,x,y,ans,f[1000005],vis[1000005];
 4 int find(int k){
 5     if (k==f[k])return k;
 6     return f[k]=find(f[k]);
 7 }
 8 int main(){
 9     scanf("%d",&n);
10     for(int i=1;i<=n+1;i++)f[i]=i;
11     for(int i=1;i<=n;i++){
12         scanf("%d%d",&x,&y);
13         if (find(x)==find(y))vis[find(x)]=1;
14         else{
15             if (find(x)>find(y))swap(x,y);
16             vis[find(y)]|=vis[find(x)];
17             vis[find(x)]=1;
18             f[find(x)]=find(y);
19         }
20     }
21     ans=1;
22     while (vis[ans])ans++;
23     printf("%d",ans-1);
24 } 
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11875146.html