ZOJ1157

来源:互联网 发布:打印机无法配置该端口 编辑:程序博客网 时间:2024/06/01 09:00
最大二分匹配
 
一些设备需要固定型号的插座,有的插座可以通过另一种设备得到。
 
样例
 
 






laptop B 
phone C 
pager B 
clock B 
comb X 

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;  }  


原创粉丝点击