看到一个讲得很好的:二分图的最大匹配,完美匹配,匈牙利算法
还有一个特别详细的:matching
uva,10080
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int maxn=110; int n,m,s,v; int pos; struct Point { double x,y; void read() { scanf("%lf%lf",&x,&y); } }p[maxn],q[maxn]; double dist(Point a,Point b) { double dx=a.x-b.x; double dy=a.y-b.y; return sqrt(dx*dx+dy*dy); } struct Edge { int from,to; Edge(){} Edge(int a,int b):from(a),to(b){} }E[maxn*maxn]; vector<Edge> edges; //记录边 vector<int> G[maxn]; //记录从i出发的遍的编号 int matching[maxn+5]; bool check[maxn+5]; typedef vector<int>::iterator iterator_t; bool dfs(int u) { for(iterator_t it=G[u].begin();it!=G[u].end();it++) { int v=edges[*it].to; if(!check[v]) { check[v]=true; if(matching[v]==-1 || dfs(matching[v])) { matching[v]=u; //显示v与u匹配 return true; //加上matching[u]=v是错的,因为matching[u] //是在u之前与u匹配的点,命为w,这样覆盖了w,下次经过u,w这一条匹配 //边的时候就会出错。 //!!!!!!!注意当二分匹配的两部分点的编号不一样的时候是对的。 //也可以分拆问题,一个区间段是一个类型,然后匹配; } } } return false; } int hungarian() { int ans=0; memset(matching,-1,sizeof(matching)); for(int u=0;u<n;++u) {//if(matching[u]==-1)是错的,因为增广路径是可以经过已经匹配的点 memset(check,false,sizeof(check)); if(dfs(u)) ++ans; } return ans; } int main() { while(~scanf("%d%d%d%d",&n,&m,&s,&v)) { for(int i=0;i<n;i++) { G[i].clear(); p[i].read(); } for(int i=0;i<m;i++) { q[i].read(); } edges.clear(); pos=0; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(dist(p[i],q[j])<=s*v) { G[i].push_back(pos); E[pos]=Edge(i,j); edges.push_back(E[pos]); pos++; } } } printf("%d\n",n-hungarian()); } return 0; }
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <vector> 6 #include <algorithm> 7 8 using namespace std; 9 const int maxn=110; 10 int n,m,s,v; 11 int pos; 12 13 14 struct Point 15 { 16 double x,y; 17 void read() 18 { 19 scanf("%lf%lf",&x,&y); 20 } 21 }p[maxn],q[maxn]; 22 23 double dist(Point a,Point b) 24 { 25 double dx=a.x-b.x; 26 double dy=a.y-b.y; 27 return sqrt(dx*dx+dy*dy); 28 } 29 30 vector<int> G[maxn]; 31 int matching[maxn+5]; 32 bool check[maxn+5]; 33 typedef vector<int>::iterator iterator_t; 34 35 36 bool dfs(int u) 37 { 38 for(int i=0;i<G[u].size();i++) 39 { 40 int v=G[u][i]; 41 if(!check[v]) 42 { 43 check[v]=true; 44 if(matching[v]==-1 || dfs(matching[v])) 45 { 46 matching[v]=u; 47 return true; 48 } 49 } 50 } 51 return false; 52 } 53 54 int hungarian() 55 { 56 int ans=0; 57 memset(matching,-1,sizeof(matching)); 58 for(int u=0;u<n;++u) 59 { 60 memset(check,false,sizeof(check)); 61 if(dfs(u)) 62 ++ans; 63 } 64 return ans; 65 } 66 67 int main() 68 { 69 while(~scanf("%d%d%d%d",&n,&m,&s,&v)) 70 { 71 for(int i=0;i<n;i++) 72 { 73 G[i].clear(); 74 p[i].read(); 75 } 76 77 for(int i=0;i<m;i++) 78 { 79 q[i].read(); 80 } 81 for(int i=0;i<n;i++) 82 { 83 for(int j=0;j<m;j++) 84 { 85 if(dist(p[i],q[j])<=s*v) 86 { 87 G[i].push_back(j); 88 } 89 } 90 } 91 printf("%d\n",n-hungarian()); 92 } 93 return 0; 94 }