描述
随着社会的不断发展,人与人之间的感情越来越功利化。最近,爱神丘比特发现,爱情也已不再是完全纯洁的了。这使得丘比特很是苦恼,他越来越难找到合适的男女,并向他们射去丘比特之箭。于是丘比特千里迢迢远赴中国,找到了掌管东方人爱情的神——月下老人,向他求教。
月下老人告诉丘比特,纯洁的爱情并不是不存在,而是他没有找到。在东方,人们讲究的是缘分。月下老人只要做一男一女两个泥人,在他们之间连上一条红线,那么它们所代表的人就会相爱——无论他们身处何地。而丘比特的爱情之箭只能射中两个距离相当近的人,选择的范围自然就小了很多,不能找到真正的有缘人。
丘比特听了月下老人的解释,茅塞顿开,回去之后用了人间的最新科技改造了自己的弓箭,使得丘比特之箭的射程大大增加。这样,射中有缘人的机会也增加了不少。
情人节(Valentine's day)的午夜零时,丘比特开始了自己的工作。他选择了一组数目相等的男女,感应到他们互相之间的缘分大小,并依此射出了神箭,使他们产生爱意。他希望能选择最好的方法,使被他选择的每一个人被射中一次,且每一对被射中的人之间的缘分的和最大。
当然,无论丘比特怎么改造自己的弓箭,总还是存在缺陷的。首先,弓箭的射程尽管增大了,但毕竟还是有限的,不能像月下老人那样,做到“千里姻缘一线牵”。其次,无论怎么改造,箭的轨迹终归只能是一条直线,也就是说,如果两个人之间的连线段上有别人,那么莫不可向他们射出丘比特之箭,否则,按月下老人的话,就是“乱点鸳鸯谱”了。
作为一个凡人,你的任务是运用先进的计算机为丘比特找到最佳的方案。
格式
输入格式
输入第一行为正整数k,表示丘比特之箭的射程,第二行为正整数n(n<30),随后有2n行,表示丘比特选中的人的信息,其中前n行为男子,后n行为女子。每个人的信息由两部分组成:他的姓名和他的位置。姓名是长度小于20且仅包含字母的字符串,忽略大小写的区别,位置是由一对整数表示的坐标,它们之间用空格分隔。格式为x y Name。输入文件剩下的部分描述了这些人的缘分。每一行的格式为Name1 Name2 p。Name1和Name2为有缘人的姓名,p是他们之间的缘分值(p为小于等于255的正整数)。以一个End作为文件结束标志。每两个人之间的缘分至多只被描述一次。如果没有被描述,则说明他们缘分值为1。
输出格式
输出仅一个正整数,表示每一对被射中的人之间的缘分的总和。这个和应当是最大的。
样例1
样例输入1
2 3 0 0 Adam 1 1 Jack 0 2 George 1 0 Victoria 0 1 Susan 1 2 Cathy Adam Cathy 100 Susan George 20 George Cathy 40 Jack Susan 5 Cathy Jack 30 Victoria Jack 20 Adam Victoria 15 End
样例输出1
65
不想吐槽了。。。。。
首先是题目描述,样例明明是先读入坐标(x,y)在读入名字,但是题目描述是先名字后坐标。。。。纠结了好久。。。。
抱着试一试的心态才知道是先坐标后名字
题目说的没有重边,但是数据有!
得知数据有重边后我又判断,取最优的那条边,但是数据是取的最后出现的那条边!
还有,几何不好的孩子太苦逼了。。。。。。
下面是我们需要注意的几点
1.弓箭的射程有限。
2.箭的轨迹只能是一条直线,两个人之间的连线段不能有别人。
3.忽略大小写的区别。
4.如果没有被描述,则说明他们缘分值为1,但并不一定有边!(即在射程内)
6.重边取最后一条
关键是第二点。判了好久啊。。。。。。。。。。。。。。。。。。。。。
做了一上午,都在判第二点。。。。。。
测评情况(Vijos):

C++ AC Code
/*http://blog.csdn.net/jiangzh7
By Jiangzh*/
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
const int N=1000;
const int inf=0x3f3f3f3f;
#define sqr(_) ((_)*(_))
typedef long long LL;
int K,n;
struct node{char name[50];int x,y;}p[N];
int cap[N][N],cost[N][N];
int S,T;
int dist[N],h[N],pre[N];
queue<int> q;
void predoing(char *s)//全部转化为小写
{
int len=strlen(s);
for(int i=0;i<len;i++) s[i]=tolower(s[i]);
}
void read()
{
scanf("%d%d\n",&K,&n);
for(int i=1;i<=n*2;i++)
{
scanf("%d%d%s\n",&p[i].x,&p[i].y,p[i].name);
predoing(p[i].name);
}
}
int find(char *s)//找到对应名字的序号
{
for(int i=1;i<=n*2;i++)
if(!strcmp(s,p[i].name)) return i;
}
double dis(int x1,int y1,int x2,int y2)//距离
{
return sqrt((double)sqr((LL)x1-x2)+(double)sqr((LL)y1-y2));
}
bool check(int i,int j)//检查能否连边
{
int x1=p[i].x,y1=p[i].y;
int x2=p[j].x,y2=p[j].y;
if(dis(x1,y1,x2,y2)>(double)K) return false;
for(int i=1;i<=n+n;i++)
{
if(p[i].x==x1&&p[i].y==y1) continue;
if(p[i].x==x2&&p[i].y==y2) continue;
int x0=p[i].x,y0=p[i].y;
if((x0-x1)*(x0-x2)<=0 && (y0-y1)*(y0-y2)<=0)
if((x0-x1)*(y2-y1)==(y0-y1)*(x2-x1))//p在boy和girl连线上
return false;
}
return true;
}
void build_map()//建图
{
char b[50],g[50];
for(int i=1;i<=n;i++)
for(int j=n+1;j<=n+n;j++)
if(dis(p[i].x,p[i].y,p[j].x,p[j].y)<=K)//必须在射程内
{
cap[i][j]=1;
cost[i][j]=1;
cost[j][i]=-1;
}
int x,y,w;
while(1)
{
memset(b,0,sizeof(b));
memset(g,0,sizeof(g));
scanf("%s",b);if(!strcmp(b,"End")) break;
scanf("%s%d\n",g,&w);
predoing(b);predoing(g);
x=find(b);y=find(g);
if(x>y) swap(x,y);//不一定是男在前,所以必要的时候交换一下位置
if(check(x,y))
{
cost[x][y]=w;
cost[y][x]=-w;
}
}
S=0;T=n+n+1;//源点和汇点
for(int i=1;i<=n;i++) {cap[S][i]=1;cost[S][i]=0;}
for(int i=n+1;i<=n+n;i++) {cap[i][T]=1;cost[i][T]=0;}
}
bool spfa()
{
for(int i=S;i<=T;i++) dist[i]=-inf;
dist[S]=0;q.push(S);
while(!q.empty())
{
int x=q.front();
q.pop();h[x]=false;
for(int i=S;i<=T;i++)
if(cap[x][i]>0 && dist[i]<dist[x]+cost[x][i])
{
pre[i]=x;
dist[i]=dist[x]+cost[x][i];
if(!h[i])
{
h[i]=true;
q.push(i);
}
}
}
return dist[T]!=-inf;
}
void work()
{
build_map();
int maxcost=0;
while(spfa())
{
int res=inf;
for(int i=T;i!=S;i=pre[i])
{
res=min(res,cap[pre[i]][i]);
}
for(int i=T;i!=S;i=pre[i])
{
cap[pre[i]][i]-=res;
cap[i][pre[i]]+=res;
}
maxcost+=res*dist[T];
}
printf("%d\n",maxcost);
}
int main()
{
freopen("cupid.in","r",stdin);
freopen("cupid.out","w",stdout);
read();
work();
return 0;
}

该博客讨论了Vijos 1169题目的解决过程,涉及最大费用流和最优匹配。丘比特试图在有限射程内寻找缘分最大化的男女匹配,博客介绍了输入输出格式,并分享了因数据格式和规则理解错误导致的困扰,如重边处理、射程限制和缘分默认值等问题,强调了正确理解题目细节的重要性。
1149

被折叠的 条评论
为什么被折叠?



