题解:
KM匹配
注意判断不能在一条直线上
然后大小写相同
代码:
#include<bits/stdc++.h> using namespace std; const int N=4005; map<string,int> MP; float R,x[N],y[N]; int G[N][N],n,p,a,b,l[N],r[N],slack[N],con[N],vy[N],vx[N]; int on(int a,int b,int c) { if (x[a]==x[b]&&x[b]==x[c]) return (min(y[a],y[b])<=y[c]&&y[c]<=max(y[a],y[b])); return ((y[a]-y[b])*(x[c]-x[b])==(y[c]-y[b])*(x[a]-x[b])); } int Judge(int a,int b) { if (x[a]>x[b]) swap(a,b); for (int i=1;i<=n*2;i++) if (i!=a&&i!=b&&x[a]<=x[i]&&x[i]<=x[b]) if (on(a,b,i)) return 0; return 1; } float dis(int a,int b) { return (x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]); } void Preoperate() { memset(l,0,sizeof(l)); for (int i=1;i<=2*n;i++) for (int j=1;j<=2*n;j++) l[i]=max(l[i],G[i][j]); memset(r,0,sizeof(r)); } int find(int x) { vx[x]=1; for (int i=n+1;i<=2*n;i++) if (!vy[i]) { if (G[x][i]==l[x]+r[i]) { vy[i]=1; if (con[i]==-1||find(con[i])) { con[i]=x; return 1; } } else slack[i]=min(slack[i],l[x]+r[i]-G[x][i]); } return 0; } int main() { memset(G,-0x3f,sizeof(G)); string str; scanf("%f%d",&R,&n); for (int i=1;i<=2*n;i++) { scanf("%f %f",&x[i],&y[i]); cin>>str; for (int j=0;j<str.length();j++) if (str[j]<='Z'&&str[j]>='A') str[j]+='a'-'A'; MP[str]=i; } while (1) { cin>>str; if (str=="End") break; for (int i=0;i<str.length();i++) if (str[i]<='Z'&&str[i]>='A') str[i]+='a'-'A'; a=MP[str]; cin>>str; for (int i=0;i<str.length();i++) if (str[i]<='Z'&&str[i]>='A') str[i]+='a'-'A'; b=MP[str]; scanf("%d",&p); if (a>b) swap(a,b); if (dis(a,b)<=R*R&&Judge(a,b)) G[a][b]=p; } for (int i=1;i<=n;i++) for (int j=n+1;j<=2*n;j++) if(G[i][j]<0&&dis(i,j)<=R*R&&Judge(i,j)) G[i][j]=1; Preoperate(); memset(con,-1,sizeof(con)); for (int j=1;j<=n;j++) { for (int k=1;k<=1000;k++) { memset(slack,127,sizeof(slack)); memset(vx,0,sizeof(vx)); memset(vy,0,sizeof(vy)); if (find(j)) break; int d=2e9; for (int i=n+1;i<=n*2;i++) if (!vy[i]) d=min(d,slack[i]); for (int i=1;i<=n;i++) if(vx[i]) l[i]-=d; for (int i=n+1;i<=n*2;i++) if(vy[i]) r[i]+=d; } } int ans=0; for (int i=1;i<=n*2;i++) if (con[i]!=-1) ans+=G[con[i]][i]; printf("%d ",ans); return 0; }