最大二分匹配
一些设备需要固定型号的插座,有的插座可以通过另一种设备得到。
样例
4
A
B
C
D
5
laptop B
phone C
pager B
clock B
comb X
3
B X
X A
X D
一.数据结构
1.插头插座类型为字符串,需映射成数字。
2.给字符串编号
二.每个插头使用适配器后,可以匹配的插座类型
1.计算匹配功能由函数完成
2.计算适配器匹配的插座类型的算法
ps:匹配结果存储在相应插头的数组list中。由于适配器可以插入其他适配器,
所以使用一个适配器后,要重新搜索一遍。
三.建立插头与插座的对应关系
1.使用辅助数组帮助匹配关系的建立:
插头与插座匹配的关系存储在数组matchPlug[100]中。
插座与插头匹配的关系存储在数组matchRecep[100]中。与前者相对称。
2.对每个插头,寻找与之匹配的插座
3.建立插头与插座对应关系算法
ps:若该插头找到匹配插座,就找下一个插头(i++);如果该插头还没有匹配,
就通过回溯算法寻找匹配插座,因为改变匹配状态,需要重新开始搜索(i=0)
4.应用回溯算法,搜索插头与插座的对应关系
5.插头node和所有插座匹配,是完全numReceps叉树
四.统计哪些插头没有找到插座
第一部分和第二部分的名字是没有重复的。
一些设备需要固定型号的插座,有的插座可以通过另一种设备得到。
样例
4
A
B
C
D
5
laptop B
phone C
pager B
clock B
comb X
3
B X
X A
X D
有ABCD四种插座,其中comb的插头是X型号的,而A,D上有X型号的插孔,所以相当于,comb可以和A,D相连。
建图后,用floyd把所有点能连通的都连下,然后匈牙利算法即可。当然不在已知插座里的插座肯定是不能用的。
一.数据结构
1.插头插座类型为字符串,需映射成数字。
2.给字符串编号
二.每个插头使用适配器后,可以匹配的插座类型
1.计算匹配功能由函数完成
2.计算适配器匹配的插座类型的算法
ps:匹配结果存储在相应插头的数组list中。由于适配器可以插入其他适配器,
所以使用一个适配器后,要重新搜索一遍。
三.建立插头与插座的对应关系
1.使用辅助数组帮助匹配关系的建立:
插头与插座匹配的关系存储在数组matchPlug[100]中。
插座与插头匹配的关系存储在数组matchRecep[100]中。与前者相对称。
2.对每个插头,寻找与之匹配的插座
3.建立插头与插座对应关系算法
ps:若该插头找到匹配插座,就找下一个插头(i++);如果该插头还没有匹配,
就通过回溯算法寻找匹配插座,因为改变匹配状态,需要重新开始搜索(i=0)
4.应用回溯算法,搜索插头与插座的对应关系
5.插头node和所有插座匹配,是完全numReceps叉树
四.统计哪些插头没有找到插座
1.数组中,值为-1的插头没有找到插座,将他们统计出来即可。
第一部分和第二部分的名字是没有重复的。
#include
#include
#include
#include
#include
#include
#define MAX 1010
using namespace std;
vectorname;
bool can[MAX][MAX];
string recept[MAX];
string device[MAX];
bool map[MAX][MAX];
bool visit[MAX];
int match[MAX];
int n,p;
bool find(int k)
{
int i,j;
for(i=1;i<=n;i++)
{
if(map[k][i]&&visit[i]==false)
{
visit[i]=true;
if(match[i]==0||find(match[i]))
{
match[i]=k;
return true;
}
}
}
return false;
}
int hungary()
{
memset(match,0,sizeof(match));
int sum=0;
for(int i=1;i<=p;i++)
{
memset(visit,0,sizeof(visit));
if(find(i))
sum++;
}
return sum;
}
int getnum(string s)
{
vector::iterator p;
p=find(name.begin(),name.end(),s);
if(p==name.end())
{
name.push_back(s);
return name.size()-1;
}
else
{
return p-name.begin();
}
}
int main()
{
int i,j,k,t;
string devname,name1,name2;
cin>>t;
while(t--)
{
name.clear();
memset(match,0,sizeof(match));
memset(can,0,sizeof(can));
memset(map,0,sizeof(map));
cin>>n;
for(i=0;i>recept[i];
getnum(recept[i]);
}
cin>>p;
for(i=0;i>devname>>device[i];
getnum(device[i]);
}
cin>>k;
for(i=0;i>name1>>name2;
int num1=getnum(name1);
int num2=getnum(name2);
can[num1][num2]=true;
}
int maxnum=name.size();
for(i=0;i
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 520
using namespace std;
char ch[MAX][30];
int map[MAX][MAX];
char str[MAX][30];
char adp[30];
int used[MAX],mat[MAX];
int n,m,nn;
int Augement(int x)
{
int i;
for(i=m+1; i<=m+nn; i++)
if( !used[i] && map[x][i] )
{
used[i] = 1;
if( !mat[i] || Augement(mat[i]) )
{
mat[i] = x;
return 1;
}
}
return 0;
}
int Hungary()
{
int i,sum = 0;
memset(mat,0,sizeof(mat));
for(i=1; i<=m; i++)
{
memset(used,0,sizeof(used));
if( Augement(i) )
sum++;
}
return sum;
}
int main()
{
int ncases;
int i,k,p,j;
char a[30],b[30];
scanf("%d",&ncases);
while( ncases-- )
{
scanf("%d",&n);
memset(map,0,sizeof(map));
for(i=1; i<=n; i++)
scanf("%s",ch[i]);
nn = n;
scanf("%d",&m);
for(i=1; i<=m; i++)
{
scanf("%s %s",str[i],adp);
int flag = 0;
for(k=1; k<=n; k++)
if( strcmp(adp,ch[k]) == 0 )
{
flag = 1;
map[i][k+m] = 1;
break;
}
if( flag == 0 )
{
n++;
memcpy(ch[n],adp,sizeof(adp));
map[i][m+n] = 1;
}
}
scanf("%d",&p);
while( p-- )
{
scanf("%s %s",a,b);
int tmpb = -1,tmpa = -1;
for(i=1; i<=n; i++)
{
if( tmpb != -1 && tmpa != -1 )
break;
if( strcmp(b,ch[i]) == 0 )
tmpb = i;
if( strcmp(a,ch[i]) == 0 )
tmpa = i;
}
if( tmpb == -1 )
{
n++;
memcpy(ch[n],b,sizeof(b));
tmpb = n;
}
if( tmpa == -1 )
{
n++;
memcpy(ch[n],a,sizeof(a));
tmpa = n;
}
map[tmpa+m][tmpb+m] = 1;
}
for(i=1; i<=m+n; i++)
for(k=1; k<=m+n; k++)
for(j=1; j<=m+n; j++)
if( map[k][i] && map[i][j] && !map[k][j] )
map[k][j] = 1;
int ans = Hungary();
printf("%d/n",m-ans);
if( ncases )
printf("/n");
}
return 0;
}