bzoj 2539: [Ctsc2000]丘比特的烦恼 (KM算法)
来源:互联网 发布:单片机原理及应用pdf 编辑:程序博客网 时间:2024/06/02 19:41
题目描述
传送门
题解
KM的裸题吧,就是细节比较恶心。。。。
代码
#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>#include<cmath>#include<map>#define N 103#define inf 1000000000using namespace std;double dis,dx[N],dy[N],fx[N],fy[N]; int n,val[N][N],cx[N],cy[N],pdx[N],pdy[N],belong[N],slack[N];map<string,int> mp;string s,g,b;bool check(int ii,int jj){ double x=dx[ii],y=dy[ii],x1=fx[jj],y1=fy[jj]; if (x>x1) swap(x,x1),swap(y,y1); for (int i=1;i<=n;i++) if (dx[i]>=min(x,x1)&&dx[i]<=max(x,x1)&&dy[i]>=min(y,y1)&&dy[i]<=max(y,y1)){ if (ii==i) continue; if (x==x1) return false; double k=(dy[i]-y)/(dx[i]-x); double k1=(y1-y)/(x1-x); if (k==k1) return false; } for (int i=1;i<=n;i++) if (fx[i]>=min(x,x1)&&fx[i]<=max(x,x1)&&fy[i]>=min(y,y1)&&fy[i]<=max(y,y1)){ if (i==jj) continue; if (x==x1) return false; double k=(fy[i]-y)/(fx[i]-x); double k1=(y1-y)/(x1-x); if (k==k1) return false; } return true;}bool dfs(int x){ pdx[x]=1; for (int i=1;i<=n;i++){ if (pdy[i]) continue; int gap=cx[x]+cy[i]-val[x][i]; if(!gap) { pdy[i]=1; if (!belong[i]||dfs(belong[i])) { belong[i]=x; return true; } }else slack[i]=min(gap,slack[i]); } return false;}int km(){ memset(belong,0,sizeof(belong)); memset(cy,0,sizeof(cy)); for (int i=1;i<=n;i++) { cx[i]=val[i][1]; for (int j=1;j<=n;j++) cx[i]=max(cx[i],val[i][j]); } for (int i=1;i<=n;i++) { for (int j=1;j<=n;j++) slack[j]=inf; while (true) { memset(pdx,0,sizeof(pdx)); memset(pdy,0,sizeof(pdy)); if(dfs(i)) break; int d=inf; for (int j=1;j<=n;j++) if (!pdy[j]) d=min(d,slack[j]); for (int j=1;j<=n;j++) if (pdx[j]) cx[j]-=d; for (int j=1;j<=n;j++) if (pdy[j]) cy[j]+=d; else slack[j]-=d; } } int ans=0; for (int i=1;i<=n;i++) if (val[belong[i]][i]!=-inf) ans+=val[belong[i]][i]; return ans;}double pow(double x){ return x*x; }double getdis(double x,double y,double x1,double y1){ return sqrt(pow(x-x1)+pow(y-y1)); }int main(){ freopen("a.in","r",stdin); scanf("%lf",&dis); scanf("%d",&n); for (int i=1;i<=n;i++) { cin>>dx[i]>>dy[i]>>s; int l=s.length(); for (int j=0;j<l;j++) if (s[j]>='A'&&s[j]<='Z') s[j]+=32; mp[s]=i; } for (int i=1;i<=n;i++) { cin>>fx[i]>>fy[i]>>s; int l=s.length(); for (int j=0;j<l;j++) if (s[j]>='A'&&s[j]<='Z') s[j]+=32; mp[s]=i+n; } for(int i=1;i<=n;i++) for (int j=1;j<=n;j++) val[i][j]=-inf; while (true) { int x; cin>>g; if (g=="End") break; cin>>b>>x; int l=g.length(); for (int k=0;k<l;k++) if (g[k]>='A'&&g[k]<='Z') g[k]+=32; l=b.length(); for (int k=0;k<l;k++) if (b[k]>='A'&&b[k]<='Z') b[k]+=32; int i=mp[g]; int j=mp[b]; if (i>j) swap(i,j); j-=n; if (check(i,j)&&getdis(dx[i],dy[i],fx[j],fy[j])<=dis) val[i][j]=x; } for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (i!=j&&check(i,j)&&getdis(dx[i],dy[i],fx[j],fy[j])<=dis) val[i][j]=max(val[i][j],1); printf("%d\n",km());}
0 0
- bzoj 2539: [Ctsc2000]丘比特的烦恼 (KM算法)
- [KM算法] BZOJ 2539 [Ctsc2000]丘比特的烦恼
- [BZOJ2539][Ctsc2000]丘比特的烦恼(KM+计算几何)
- [BZOJ2539][CTSC2000][KM]丘比特的烦恼
- #HYSBZ-2539#[CTSC2000]丘比特的烦恼
- BZOJ2539: [Ctsc2000]丘比特的烦恼
- BZOJ 2539 [Ctsc2000]丘比特的烦恼 带权二分图的最佳匹配
- 【二分图最佳匹配】丘比特的烦恼
- wikioi 丘比特的烦恼 (最大权匹配)
- 【二分图匹配】【CSTC2000】丘比特的烦恼
- 【bzoj 2541】 [Ctsc2000]冰原探险(BFS)
- 【最大费用流】【最优匹配】丘比特的烦恼 Vijos 1169
- bzoj 2539 KM匹配
- bzoj 2541: [Ctsc2000]冰原探险 (bfs+建图)
- BZOJ 3571 [HNOI 2014] 画框 (KM算法+分治)
- bzoj 1937: [Shoi2004]Mst 最小生成树 (KM算法)
- bzoj 3281: 小P的烦恼 支配树算法+dp
- 【BZOJ2539】【codevs1221】丘比特的烦恼,trie树+几何判断+费用流
- 二分搜索的递归实现算法
- Android分组悬浮列表实现
- [LeetCode]283. Move Zeroes
- Spring:基于注解的Spring MVC(下)
- 多线程
- bzoj 2539: [Ctsc2000]丘比特的烦恼 (KM算法)
- 用于FUZZ测试的程序及其详解
- 栈的基本操作和实现C++模板类
- mysql
- Git Push 避免用户名和密码方法
- 终于知道cocos2dx的cocos studio是被谁做烂得
- Spring:基于注解的Spring MVC(上)
- 隐马尔科夫模型的应用实例:中文分词
- HDU4404 Worms(计算多边形和圆的重叠面积)