KM(带权二分图匹配)的裸题,就是构图和细节恶心。。
感觉今天一直在搞二分图匹配。。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<map> using namespace std; map<string,int>mp; char ss[10]; void Rose_max() { int len=strlen(ss); for(int i=0;i<len;i++) if(‘A‘<=ss[i]&&ss[i]<=‘Z‘)ss[i]=ss[i]-‘A‘+‘a‘; } struct people { int x,y; }p[110]; bool v[110][110]; //---------------------- int n; int love[110][110]; int exg[110],exb[110]; bool vg[110],vb[110]; int match[110],need[110]; bool findboy(int x) { vg[x]=true; for(int i=1;i<=n;i++) { if(vb[i]==false) { int gap=exg[x]+exb[i]-love[x][i]; if(gap==0) { vb[i]=true; if(match[i]==0||findboy(match[i])==true) { match[i]=x; return true; } } else need[i]=min(need[i],gap); } } return false; } void KM() { memset(match,0,sizeof(match)); memset(exb,0,sizeof(exb)); for(int i=1;i<=n;i++) { exg[i]=0; for(int j=1;j<=n;j++) exg[i]=max(exg[i],love[i][j]); }//init for(int i=1;i<=n;i++) { memset(need,63,sizeof(need)); while(1) { memset(vg,false,sizeof(vg)); memset(vb,false,sizeof(vb)); if(findboy(i)==true)break; int d=2147483647; for(int j=1;j<=n;j++) if(vb[j]==false)d=min(d,need[j]); for(int j=1;j<=n;j++) { if(vg[j]==true)exg[j]-=d; if(vb[j]==true)exb[j]+=d; else need[j]-=d; } } } int ans=0; for(int i=1;i<=n;i++) ans+=love[match[i]][i]; printf("%d\n",ans); } //-----------KM-------------------------- int main() { freopen("cupid.in","r",stdin); freopen("cupid.out","w",stdout); int K,x,y; scanf("%d%d",&K,&n); for(int i=1;i<=2*n;i++) { scanf("%d%d",&p[i].x,&p[i].y); memset(ss,0,sizeof(ss));scanf("%s",ss);Rose_max(); mp[ss]=i; } for(int i=1;i<=n;i++) for(int j=n+1;j<=2*n;j++) if((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y)<=K*K) { v[i][j]=true; for(int k=1;k<=n*2;k++) { if(k!=i&&k!=j) { int x1=p[i].x,y1=p[i].y,x2=p[j].x,y2=p[j].y,x3=p[k].x,y3=p[k].y; if(((x1<=x3&&x3<=x2)||(x1>=x3&&x3>=x2))&&((y1<=y3&&y3<=y2)||(y1>=y3&&y3>=y2))) if((y3-y1)*(x3-x2)==(y3-y2)*(x3-x1)) {v[i][j]=false;break;} } } } memset(love,-63,sizeof(love)); for(int i=1;i<=n;i++) for(int j=n+1;j<=2*n;j++) if(v[i][j]==true)love[i][j-n]=1; while(1) { memset(ss,0,sizeof(ss));scanf("%s",ss);Rose_max(); if(ss[0]==‘e‘&&ss[1]==‘n‘&&ss[2]==‘d‘&&strlen(ss)==3)break; int p1=mp[ss]; memset(ss,0,sizeof(ss));scanf("%s",ss);Rose_max(); int p2=mp[ss]; if(p2<=n)swap(p1,p2); scanf("%d",&x); if(v[p1][p2]==true)love[p1][p2-n]=x; } //------init------------ KM(); return 0; }