二分图最大分配

二分图是一个无向图,分为x,y两部分,x部中的点与y中的点每每会存在多条无向边,若x1与y2之间存在一条边,那么x1与y2能够“分配”,固然每一个点部止局限于只有一条边,能够有多条,因此又有多种分配方法,为达到让这个二分图中分配数量最大,即便x1与y2能够“分配”也只是暂时的,由于要为其余点“让步”,举个例子:ios

图中,点1到点2有一条边,点1到点3有一条边,点2到点4有一条边git

就“择近原则”,点1能够首先和点2“分配”,但点3发现本身只有点1能够“分配”,因而就向点1提出要求“分配”,但是点1已经被“分配过了”,因而点1就去找点2商量问它可不能够找另外一个点“分配”,点2就去询问点4可否“分配”,发现点4尚未被“分配”,也就是说点2能够找另外一个点分配,因而返回true,不和点1“分配”了,和点4分配,点1获得true便与点3“分配”了算法

细心的人可能会发现,若是像开始那样:点1与点2分配,那么只有1个“分配组”,而通过这一系列算法(匈牙利算法)而拓展路线(增广路)便有2个“分配组”,这就称为二分图最大分配ide

题目连接函数

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 using namespace std;  5 int m;  6 int n;  7 int x,y;  8 int ans;  9 int match[210];                                  //记录分配目标 
10 int put[110][3];                                 //输出 
11 bool book[210];                                  //记录剪枝 
12 bool way[210][210];                              //记录无向图的边 
13 inline int read()                                //快速读入 
14 { 15     int sign=1,num=0; 16     char ch=getchar(); 17     while(!isdigit(ch)){if(ch=='-')sign=-1;ch=getchar();} 18     while(isdigit(ch)){num=num*10+(ch-'0');ch=getchar();} 19     return sign*num; 20 } 21 void init()                                      //读入函数 
22 { 23     m=read(); 24     n=read(); 25     while(x!=-1&&y!=-1) 26  { 27         x=read();                                //无向边存两次 
28         y=read(); 29         way[x][y]=true; 30         way[y][x]=true; 31  } 32 } 33 bool dfs(int x) 34 { 35     for(int y=m+n;y>0;--y) 36  { 37         if(way[x][y]&&book[y]==false)            //枚举点x的边 
38  { 39             book[y]=true;                        //记录点y已被查找(并不是分配) 
40             if(match[y]==0||dfs(match[y]))       //若y没有被分配或与y分配的人还有"退"的余地 
41  { 42                 match[x]=y;                      //储存分配目标 
43                 match[y]=x; 44                 return true; 45  } 46  } 47  } 48     return false; 49 } 50 int main()                                       //看代码建议从mian函数看起 
51 { 52  init(); 53     for(int i=1;i<=m+n;++i)                      //枚举点 
54  { 55         memset(book,false,sizeof(book)); 56  dfs(i); 57  } 58     for(int i=1;i<=m+n;++i) 59         if(match[i]!=0&&match[match[i]]!=0)       //防止重复输出 
60  { 61             put[++ans][1]=i; 62             put[ans][2]=match[i]; 63             match[match[i]]=0; 64  } 65     if(ans==0)                                   //特判 
66  { 67         puts("No Solution!"); 68         return 0; 69  } 70     printf("%d",ans); 71     for(int i=1;i<=ans;++i) 72         printf("\n%d %d",put[i][1],put[i][2]); 73 }
View Code
相关文章
相关标签/搜索