又是一道二分图匹配,只是这个题,节点多,建图也比较麻烦,要不是别人提醒,都想不到二分图匹配,其实ACM练的最重要的东西就是这种问题的抽象能力,这比掌握任何一种算法,能打的出来代码重要的多,也难得多,这个题每两个单词不匹配就在两个编号之间连一条边,找到最大匹配,就是至少要改掉的数目,剩下的就是最多的正确的数目
View Code
1 #include<stdio.h> 2 #include<string.h> 3 #define N 2005 4 #define M 505 5 int match[M]; 6 bool used[M]; 7 int t,head[M]; 8 struct word 9 { 10 int id; 11 char c; 12 }; 13 word map[N][N]; 14 char s[N]; 15 struct edge 16 { 17 int v,next; 18 }; 19 edge e[N*N]; 20 void add(int u,int v) 21 { 22 e[t].v=v; 23 e[t].next=head[u]; 24 head[u]=t++; 25 } 26 void init() 27 { 28 memset(match,-1,sizeof(match)); 29 memset(head,-1,sizeof(head)); 30 memset(map,0,sizeof(map)); 31 t=0; 32 } 33 bool dfs(int u) 34 { 35 int i,v; 36 for(i=head[u];i>=0;i=e[i].next) 37 { 38 v=e[i].v; 39 if(!used[v]) 40 { 41 used[v]=true; 42 if(match[v]==-1||dfs(match[v])) 43 { 44 match[v]=u; 45 return true; 46 } 47 } 48 } 49 return false; 50 } 51 int main() 52 { 53 int n,m,sum,len; 54 int i,j,k,tcs; 55 int x,y; 56 scanf("%d",&tcs); 57 while(tcs--) 58 { 59 scanf("%d%d",&n,&m); 60 init(); 61 for(i=1;i<=n;i++) 62 { 63 scanf("%d%d",&x,&y); 64 scanf("%s",s); 65 for(j=0;j<=strlen(s);j++) 66 { 67 map[y][x+j].c=s[j]; 68 map[y][x+j].id=i; 69 } 70 } 71 for(i=1;i<=m;i++) 72 { 73 scanf("%d%d",&x,&y); 74 scanf("%s",s); 75 j=0; 76 while(s[j]) 77 { 78 if(map[y+j][x].c!='\0'&&map[y+j][x].c!=s[j]) 79 { 80 add(i,map[y+j][x].id); 81 } 82 j++; 83 } 84 } 85 sum=0; 86 for(i=1;i<=m;i++) 87 { 88 memset(used,0,sizeof(used)); 89 if(dfs(i)) 90 sum++; 91 } 92 printf("%d\n",n+m-sum); 93 } 94 return 0; 95 }