题目链接: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 }