[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 }