题意:
n个装备,每种装备都有2个属性值,分别用[1,10000]之间的数表示。使用某种装备时,只能使用该装备的某一个属性。并且每种装备最多只能使用一次。攻击boss的装备所使用的属性值必须从1开始连续递增地攻击,才能对boss产生伤害。求最多能连续攻击boss多少次。
题解:
本题竟然用并查集!把每个装备看成1条无向边,当n条边没有组成一个环时,则一共可以得到n-1个属性,如果n条边组成了一个环,则可以得到n个属性。因此可以使用并查集,根据它除了并操作不会改变根节点的性质,用它维护一个vis数组表示第i个属性能否得到,当一条边插入时,如果两个端点不在一个联通块中,就将根节点表示属性小的那个联通块连到大的那个,并将小的联通块根节点的vis置为1,大的不变;如果在一个联通块中,就将该联通块根节点vis置为1。最后枚举一下vis从1到多少均为1就是答案。
注意:因为我的程序是枚举到vis为0的那个值退出,由于属性最大是10000,所以要枚举到10001。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define inc(i,j,k) for(int i=j;i<=k;i++) 5 using namespace std; 6 7 bool vis[20000]; int fa[20000],n; 8 int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} 9 int main(){ 10 scanf("%d",&n); inc(i,1,10000)fa[i]=i; memset(vis,0,sizeof(vis)); 11 inc(i,1,n){ 12 int a,b,x,y; scanf("%d%d",&a,&b); x=find(a); y=find(b); 13 if(x==y)vis[x]=1;else{if(x>y)swap(x,y); fa[x]=y; vis[x]=1;} 14 } 15 inc(i,1,10001)if(!vis[i]){printf("%d",i-1); break;} 16 return 0; 17 }
20160520