1854. [SCOI2010]游戏【二分图】
Description
lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示。当他使用某种装备时,他只能使用该装备的某一个属性。并且每种装备最多只能使用一次。 游戏进行到最后,lxhgww遇到了终极boss,这个终极boss很奇怪,攻击他的装备所使用的属性值必须从1开始连续递增地攻击,才能对boss产生伤害。也就是说一开始的时候,lxhgww只能使用某个属性值为1的装备攻击boss,然后只能使用某个属性值为2的装备攻击boss,然后只能使用某个属性值为3的装备攻击boss……以此类推。 现在lxhgww想知道他最多能连续攻击boss多少次?
Input
输入的第一行是一个整数N,表示lxhgww拥有N种装备 接下来N行,是对这N种装备的描述,每行2个数字,表示第i种装备的2个属性值
Output
输出一行,包括1个数字,表示lxhgww最多能连续攻击的次数。
Sample Input
3
1 2
3 2
4 5
1 2
3 2
4 5
Sample Output
2
HINT
【数据范围】
对于30%的数据,保证N < =1000
对于100%的数据,保证N < =1000000
之前可能用了个假的匈牙利……也可能是我sb了
二分图之前一直用的邻接矩阵……慢的要死
改成邻接表后果然快到飞起……
然后匈牙利还学到一个新技巧:算法的for循环里不用重复memset
令ID等于当前循环的i,然后find里判断的时候就判断used的值是不是等于ID
不等于就是false,等于就是true
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 using namespace std; 7 struct node 8 { 9 int x,y,z; 10 } a[1000001]; 11 struct node1 12 { 13 int to,next; 14 } edge[2000001]; 15 int n,To[1000001],head[1000001],num_edge; 16 int used[1000001],ID; 17 18 19 bool cmp(node a,node b) 20 { 21 return a.z<b.z; 22 } 23 void add(int u,int v) 24 { 25 edge[++num_edge].to=v; 26 edge[num_edge].next=head[u]; 27 head[u]=num_edge; 28 } 29 inline int get() 30 { 31 char c; 32 int x=0,f=1; 33 c=getchar(); 34 while (c<'0'||c>'9') 35 { 36 if (c=='-') f=-1; 37 c=getchar(); 38 } 39 while (c>='0'&&c<='9') 40 { 41 x=x*10+c-'0'; 42 c=getchar(); 43 } 44 return x*f; 45 } 46 bool find(int x) 47 { 48 for (int i=head[x]; i!=0; i=edge[i].next) 49 { 50 if (used[edge[i].to]!=ID) 51 { 52 used[edge[i].to]=ID; 53 if (To[edge[i].to]==0 || find(To[edge[i].to])) 54 { 55 To[edge[i].to]=x; 56 return true; 57 } 58 } 59 } 60 return false; 61 } 62 int main() 63 { 64 n=get(); 65 for (int i=1; i<=n; ++i) 66 { 67 a[i].x=get(),a[i].y=get(); 68 add(a[i].x,i); 69 add(a[i].y,i); 70 } 71 int ans=0; 72 for (int i=1; i<=10000; ++i) 73 { 74 ID=i; 75 if (!find(i)) 76 break; 77 ++ans; 78 } 79 printf("%d",ans); 80 }