hdu 1526(最大匹配)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1526

思路:floyd求传递闭包,然后就是最大匹配了,不过一开始输入没看清,被坑了将近2个小时。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<vector>
  6 using namespace std;
  7 #define MAXN 111
  8 vector<int>vet[MAXN];
  9 bool mark[MAXN];
 10 int ly[MAXN],lx[MAXN];
 11 int Index[MAXN];
 12 int map[MAXN*5][MAXN*5];
 13 char str[MAXN*5][33];
 14 int n,m,K,vn,vm;
 15 
 16 int GetID(char ss[])
 17 {
 18     for(int i=0; i<n; i++) {
 19         if(strcmp(str[i],ss)==0)return i;
 20     }
 21     strcpy(str[n++],ss);
 22     return n-1;
 23 }
 24 
 25 void floyd()
 26 {
 27     for(int k=0; k<n; k++)
 28         for(int i=0; i<n; i++)
 29             for(int j=0; j<n; j++)
 30                 if(i==j)map[i][j]=true;
 31                 else map[i][j]=(map[i][j]||(map[i][k]&&map[k][j]));
 32 }
 33 
 34 
 35 int dfs(int u)
 36 {
 37     for(int i=0; i<vet[u].size(); i++) {
 38         int v=vet[u][i];
 39         if(!mark[v]) {
 40             mark[v]=true;
 41             if(ly[v]==-1||dfs(ly[v])) {
 42                 ly[v]=u;
 43                 lx[u]=v;
 44                 return 1;
 45             }
 46         }
 47     }
 48     return 0;
 49 }
 50 
 51 int MaxMatch()
 52 {
 53     int res=0;
 54     memset(lx,-1,sizeof(lx));
 55     memset(ly,-1,sizeof(ly));
 56     for(int i=0; i<vm; i++) {
 57         if(lx[i]==-1) {
 58             memset(mark,false,sizeof(mark));
 59             res+=dfs(i);
 60         }
 61     }
 62     return res;
 63 }
 64 
 65 int main()
 66 {
 67     //  freopen("1.txt","r",stdin);
 68     int _case,t=0;
 69     char s1[33],s2[33];
 70     scanf("%d",&_case);
 71     while(_case--) {
 72         if(t++)puts("");
 73         scanf("%d",&n);
 74         for(int i=0; i<n; i++) {
 75             scanf("%s",str[i]);
 76         }
 77         scanf("%d",&m);
 78         vn=n,vm=m;
 79         memset(map,false,sizeof(map));
 80         for(int i=0; i<m; i++)vet[i].clear();
 81         for(int i=0; i<m; i++) {
 82             scanf("%s%s",s1,s2);
 83             Index[i]=GetID(s2);
 84         }
 85         scanf("%d",&K);
 86         for(int i=0; i<K; i++) {
 87             scanf("%s%s",s1,s2);
 88             map[GetID(s1)][GetID(s2)]=true;
 89         }
 90         floyd();
 91         for(int i=0; i<vm; i++) {
 92             for(int j=0; j<vn; j++) {
 93                 if(map[Index[i]][j])vet[i].push_back(j);
 94             }
 95         }
 96         int ans=MaxMatch();
 97         printf("%d\n",m-ans);
 98     }
 99     return 0;
100 }
View Code

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值