bzoj1854 游戏 二分图

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1854

题意:给出许多组数,每组数有两个$[1,10000]$数,问从一开始最长连续上升序列有多长。每组数只能用一次。

神题啊……

首先我们可以考虑一下如果$[1,10000]$每个数用一个点来表示,每组数也用一个点来表示,那么很显然每组数都可以连出一条边指向武器编号,这个东西就显然的变成了二分图。那么直接从$1$开始跑二分图匹配即可。

跑匈牙利的注意一点:不要每次$memset$ $vis$数组,正确的做法是使用$int$版本,然后每次匹配时用计数变量更新即可。

 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(){;}
bzoj1854
posted @ 2017-09-22 12:10  ccc000111  阅读(109)  评论(0编辑  收藏  举报