记录编号 |
92336 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[CTSC 2000] 丘比特的烦恼 |
最终得分 |
100 |
用户昵称 |
cstdio |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.012 s |
提交时间 |
2014-03-19 21:33:12 |
内存使用 |
0.35 MiB |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<map>
using namespace std;
const int SIZEN=100,INF=0x7fffffff;
int N,n;//n是男女人数
int range;//射程
map<string,int> namelist;
int x[SIZEN]={0},y[SIZEN]={0};
int fate[SIZEN][SIZEN]={0};
int slack[SIZEN]={0};
bool visit[SIZEN]={0};
int lable[SIZEN]={0};
int match[SIZEN]={0};
bool findpath(int u){
visit[u]=true;
for(int i=n+1;i<=2*n;i++){
if(visit[i]||!fate[u][i]) continue;
int t=lable[u]+lable[i]-fate[u][i];
if(t==0){//在导出子图中
visit[i]=true;
if(match[i]==-1||findpath(match[i])){
match[i]=u;
return true;
}
}
else if(slack[i]>t) slack[i]=t;
}
return false;
}
int KM(void){//返回最大匹配值
memset(match,-1,sizeof(match));
for(int i=1;i<=n;i++){
lable[i]=-INF;
for(int j=n+1;j<=2*n;j++){
lable[i]=max(lable[i],fate[i][j]);
}
}
for(int i=1;i<=n;i++){
while(true){
memset(visit,0,sizeof(visit));
for(int j=n+1;j<=2*n;j++) slack[j]=INF;
if(findpath(i)) break;
int d=INF;
for(int j=n+1;j<=2*n;j++) if(!visit[j]) d=min(d,slack[j]);
for(int j=1;j<=n;j++) if(visit[j]) lable[j]-=d;
for(int j=n+1;j<=2*n;j++) if(visit[j]) lable[j]+=d;
}
}
int ans=0;
for(int i=n+1;i<=2*n;i++){
if(match[i]!=-1) ans+=fate[match[i]][i];
}
return ans;
}
int dist2(int a,int b){
return (x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]);
}
void lowercase(string &s){
for(int i=0;i<s.size();i++) if('A'<=s[i]&&s[i]<='Z') s[i]+=('a'-'A');
}
bool cross(int a,int b,int c){//b是否在ac连线上
if((y[b]-y[a])*(x[c]-x[b])!=(y[c]-y[b])*(x[b]-x[a])) return false;//不共线
if(y[a]==y[c]) return (x[a]-x[b])*(x[c]-x[b])<0;
else return (y[a]-y[b])*(y[c]-y[b])<0;
}
void init(void){
scanf("%d%d",&range,&n);
string str;
for(int i=1;i<=2*n;i++){
cin>>x[i]>>y[i]>>str;
lowercase(str);
namelist[str]=i;
}
for(int i=1;i<=n;i++) for(int j=n+1;j<=2*n;j++) fate[i][j]=fate[j][i]=1;
string n1,n2;
int p1,p2;
while(true){
cin>>n1;
if(n1=="End") break;
cin>>n2;
lowercase(n1),lowercase(n2);
p1=namelist[n1],p2=namelist[n2];
cin>>fate[p1][p2];fate[p2][p1]=fate[p1][p2];
}
for(int i=1;i<=n;i++){
for(int j=n+1;j<=2*n;j++){
if(dist2(i,j)>range*range) fate[i][j]=fate[j][i]=0;//超出射程
}
}
for(int i=1;i<=n;i++){
for(int j=n+1;j<=2*n;j++){
for(int k=1;k<=2*n;k++){
if(k==i||k==j) continue;
if(cross(i,k,j)) fate[i][j]=fate[j][i]=0;
}
}
}
}
int main(){
freopen("cupid.in","r",stdin);
freopen("cupid.out","w",stdout);
init();
printf("%d\n",KM());
return 0;
}