bzoj1854 游戏 二分图
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1854
题意:给出许多组数,每组数有两个$[1,10000]$数,问从一开始最长连续上升序列有多长。每组数只能用一次。
神题啊……
首先我们可以考虑一下如果$[1,10000]$每个数用一个点来表示,每组数也用一个点来表示,那么很显然每组数都可以连出一条边指向武器编号,这个东西就显然的变成了二分图。那么直接从$1$开始跑二分图匹配即可。
跑匈牙利的注意一点:不要每次$memset$ $vis$数组,正确的做法是使用$int$版本,然后每次匹配时用计数变量更新即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 const int maxn=10010,maxm=1000005; 7 struct node 8 { 9 int from,to,next; 10 }edge[maxm<<1]; 11 int head[maxm],tot; 12 void addedge(int u,int v) 13 { 14 edge[++tot]=(node){u,v,head[u]};head[u]=tot; 15 } 16 int vis[maxm],cnt,match[maxm],n; 17 bool findpipei(int now) 18 { 19 for(int i=head[now];i;i=edge[i].next) 20 { 21 int v=edge[i].to; 22 if(vis[v]!=cnt) 23 { 24 vis[v]=cnt; 25 if(!match[v]||findpipei(match[v])){match[v]=now;return 1;} 26 } 27 } 28 return 0; 29 } 30 int haha() 31 { 32 scanf("%d",&n); 33 for(int i=1;i<=n;i++) 34 { 35 int x,y;scanf("%d%d",&x,&y); 36 addedge(x,i);addedge(y,i); 37 } 38 for(int i=1;i<=10000;i++) 39 { 40 cnt++; 41 if(!findpipei(i)){printf("%d\n",i-1);return 0;} 42 } 43 puts("10000"); 44 } 45 int sb=haha(); 46 int main(){;}
只要是活着的东西,就算是神我也杀给你看。