题目大意: 有n个插座,下边n行分为为插座的类型,m个电器,m行分别代表电器的名称和插头的类型.
最后,有k行数据每组,对应适配器的插座和插头的类型.
思路:将所有的插座,插头编上序号,同时给自己也要标记上插座和插头(均是自身和自身间的关系),然
后给,适配器的插座和插头建立联系.之后进行Floyd的传递闭包链接有间接性关系图.最后匹配,但注意
要进行"编号"与"编号"之间的匹配.
4 A B C D 5 laptop B phone C pager B clock B comb X 3 B X X A X D
#include<iostream> #include<cstdio> #include<cstring> #include<map> #include<algorithm> using namespace std; int n,m,cro[1000],s,re[1000],gs[1000]; bool Map[1000][1000],use[1000]; char a[1000],b[1000]; void Floyd() {int i,j,k; for(k=1;k<s;k++) for(i=1;i<s;i++) for(j=1;j<s;j++) if(Map[i][k]&&Map[k][j]) Map[i][j]=true; } int DFS(int v) {int i,j,k; for(i=1;i<=n;i++) if(!use[re[i] ]&&Map[gs[v]][re[i] ]) { use[re[i] ]=true; if(cro[re[i] ]==-1||DFS(cro[ re[i] ] )) { cro[re[i] ]=v; return 1; } } return 0; } int main() {int i,j,k; map<string,int>K; while(~scanf("%d",&n)) { getchar(); K.clear();s=1;memset(cro,-1,sizeof(cro));memset(Map,false,sizeof(Map)); for(i=1;i<=n;i++) { scanf("%s",a); if(!K[a]) K[a]=s++; re[i]=K[a]; Map[re[i]][re[i]]=true; } scanf("%d",&m); for(i=1;i<=m;i++) { scanf("%s %s",a,b); if(!K[b]) K[b]=s++; gs[i]=K[b]; Map[K[b] ][K[b] ]=true; } scanf("%d",&k);getchar(); for(i=1;i<=k;i++) { scanf("%s %s",a,b); if(!K[a]) K[a]=s++; if(!K[b]) K[b]=s++; Map[K[a]][K[b]]=true; } Floyd(); int ans=0; for(i=1;i<=m;i++) {memset(use,false,sizeof(use)); ans+=DFS(i); } cout<<m-ans<<endl; } return 0; }