HDU 1054 Strategic Game(二分图匈牙利算法,最小点覆盖数,vector实现)
题目:
http://acm.hdu.edu.cn/showproblem.php?pid=1054
关于匈牙利算法的博客讲解
https://www.cnblogs.com/shenben/p/5573788.html
https://blog.csdn.net/qq_40938077/article/details/80410356
(摘自上面博客)
1 #include<bits/stdc++.h> 2 #define MAXN 9999 3 using namespace std; 4 int nx,ny;//nx表示二分图左边顶点的个数,ny表示二分图右边顶点的个数 5 int m;//m代表边的条数 6 int cx[MAXN],cy[MAXN];//如果有cx[i]=j,则必有cy[j]=i,说明i点和j点能够匹配 7 int x,y;//x点到y点有边 8 int e[MAXN][MAXN];//邻接矩阵 9 int visited[MAXN];//标记数组,标记的永远是二分图右边的顶点 10 int ret;//最后结果 11 int point(int u)//这个函数的作用是寻找增广路和更新cx,xy数组,如果找到了增广路,函数返回1,找不到,函数返回0。 12 { 13 for(int v=1;v<=ny;v++)//依次遍历右边的所有顶点 14 { 15 if(e[u][v]&&!visited[v])//条件一:左边的u顶点和右边的v顶点有连通边,条件二:右边的v顶点在没有被访问过,这两个条件必须同时满足 16 { 17 visited[v]=1;//将v顶点标记为访问过的 18 if(cy[v]==-1||point(cy[v]))//条件一:右边的v顶点没有左边对应的匹配的点,条件二:以v顶点在左边的匹配点为起点能够找到一条增广路(如果能够到达条件二,说明v顶点在左边一定有对应的匹配点)。 19 { 20 cx[u]=v;//更新cx,cy数组 21 cy[v]=u; 22 return 1; 23 } 24 } 25 } 26 return 0;//如果程序到达了这里,说明对右边所有的顶点都访问完了,没有满足条件的。 27 } 28 int main() 29 { 30 while (cin>>m>>nx>>ny) 31 { 32 memset(cx,-1,sizeof(cx));//初始化cx,cy数组的值为-1 33 memset(cy,-1,sizeof(cy)); 34 memset(e,0,sizeof(e));//初始化邻接矩阵 35 ret=0; 36 while (m--)//输入边的信息和更新邻接矩阵 37 { 38 cin>>x>>y; 39 e[x][y]=1; 40 } 41 for(int i=1;i<=nx;i++)//对二分图左边的所有顶点进行遍历 42 { 43 if(cx[i]==-1)//如果左边的i顶点还没有匹配的点,就对i顶点进行匹配 44 { 45 memset(visited,0,sizeof(visited));//每次进行point时,都要对visited数组进行初始化 46 ret+=point(i);//point函数传入的参数永远是二分图左边的点 47 } 48 } 49 cout<<ret<<endl; 50 } 51 52 }
AC代码:
1 #include<cstdio.> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 7 const int maxn=1510; 8 int linker[maxn]; 9 int vis[maxn]; 10 vector<int>Map[maxn]; 11 int n; 12 13 bool point(int u) 14 { 15 for(int i=0;i<Map[u].size();i++) 16 { 17 if(!vis[Map[u][i]])//如果没有访问过这个点 18 { 19 vis[Map[u][i]]=1;//标记访问 20 if(linker[Map[u][i]]==-1||point(linker[Map[u][i]])) 21 {//如果这条路这个点没有走过 22 linker[Map[u][i]]=u; 23 return 1; 24 } 25 } 26 } 27 return 0; 28 } 29 int hungary()//匈牙利 30 { 31 int res=0; 32 memset(linker,-1,sizeof(linker)); 33 for(int i=0;i<n;i++) 34 { 35 memset(vis,0,sizeof(vis)); 36 if(point(i)) res++; 37 } 38 return res; 39 } 40 41 int main() 42 { 43 int u,k,v; 44 while(scanf("%d",&n)!=EOF) 45 { 46 for(int i=0;i<maxn;i++)//初始化清空vector 47 Map[i].clear(); 48 for(int i=0;i<n;i++) 49 { 50 scanf("%d:(%d)",&u,&k); 51 for(int i=0;i<k;i++) 52 { 53 scanf("%d",&v); 54 Map[u].push_back(v);//u可以到v 55 Map[v].push_back(u);//v可以到u 56 } 57 } 58 printf("%d\n",hungary()/2); 59 } 60 return 0; 61 }
posted on 2019-01-20 10:59 甜甜圈不懂巧克力的苦 阅读(151) 评论(0) 编辑 收藏 举报