八中超市

Description
为了剌激消费,学校给同学们发了一些优惠劵,上面都有两个神秘的数字A,B代表返钱的数字。其值在[1,10000]。每张优惠劵只能使用一次,而且只能使用A,B中的某个数字一次,且用完后优惠劵就回收了......太奇葩了吧。J老师觉得这样玩太简单了,现在假设某个同学手中有若干张优惠劵,J老师希望这个同学首先拿出一张优惠劵出来,上面必须有数字1,然后再拿出一张优惠劵出来,上面必须有数字2......小W听了后,马上拿出手中的优惠劵,盘算着这个游戏可以进行多少轮。
Input
输入的第一行是一个整数N,表示拥有N种优惠劵
接下来N行,是对这N种优惠劵描述,每行2个数字,表示第i种优惠劵上面的2个数字
N < =1000000
Output
如题

Sample Input
3
1 2
3 2
4 5
Sample Output
2
//先使用第一张中的1,再使用第二张中的2

sol:二分图匹配

图上部为优惠券数字,下部为优惠券。数字从1开始,为每一个数字找匹配的优惠券,如果某数字找不到匹配的优惠券了,匹配结束。
代码如下:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 using namespace std;
 5 const int maxn=1000010;
 6 int n,cnt,ans;
 7 int vis[maxn],from[maxn],to[maxn<<1],next[maxn<<1],val[maxn<<1],head[maxn];
 8 void add(int a,int b)
 9 {
10     to[cnt]=b;
11     next[cnt]=head[a];
12     head[a]=cnt++;
13 }
14 int dfs(int x)
15 {
16     int i;
17     for(i=head[x];i!=-1;i=next[i])
18     {
19         if(vis[to[i]]==ans)    continue;
20         vis[to[i]]=ans;
21         if(!from[to[i]]||dfs(from[to[i]]))
22         {
23             from[to[i]]=x;
24             return 1;
25         }
26     }
27     return 0;
28 }
29 int main()
30 {
31     scanf("%d",&n);
32     int i,a,b;
33     memset(head,-1,sizeof(head));
34     for(i=1;i<=n;i++)
35     {
36         scanf("%d%d",&a,&b);
37         add(a,i),add(b,i); //添加边,将第i张优惠卷上的金额与i连边 
38     }
39     for(ans=1;ans<=n;ans++) //枚举金额为i的优惠卷,由哪张优惠劵提供 
40     {
41         if(!dfs(ans))//若当前匹配不成功了,游戏结束 
42         {
43             printf("%d",ans-1);//输出满足条件的最大匹配 
44             return 0;
45         }
46     }
47     printf("%d",n);
48     return 0;
49 }

猜你喜欢

转载自www.cnblogs.com/cutepota/p/12906089.html