您的位置:首页 > 理论基础 > 计算机网络

Gym - 101490J-思维|网络流|匈牙利-Programming Tutors

2017-09-24 20:03 344 查看
https://vjudge.net/problem/Gym-101490J

写法好多。网络流和匈牙利也得补了。

给定2*m个点,问你求 1-m 为老师,m+1-2*m为学生。

给你他们的 二维坐标,让他们两两匹配,问你他们之间距离最大值的最小值。

思路:先以老师为主,存一张二维表,然后排和每个老师 和最近学生的距离,放到一个vector里,排序,这些距离从小到大找,把用过的学生标记掉。

但是这样结果可能是错的,再以学生为主体,来一遍,求最小值。

竟然是1a 好开心qwq。实验室的说数据水。不过我感觉强弱这样都是可以得qwq

图论还是too young。匈牙利只会 最大匹配那种qwq。还是不太会qwq

#include <bits/stdc++.h>
using namespace std;
/*

*/
struct Node
{   int num,colu;

};
const int maxn=1e5;
vector<Node >a[maxn];//记录值
bool col[maxn];//记录已经用过的列标
bool cmp2(Node a,Node b){
return a.num<b.num;

}
bool cmp3(pair<int,int> a,pair<int,int> b){
return a.first<b.first;
}
int m;
int solve(){
vector<pair<int,int> >q;
memset(col,false,sizeof(col));
q.clear();
//q.resize(200);
for(int i=1;i<=m;i++){
sort(a[i].begin(),a[i].end(),cmp2);
q.push_back(make_pair(a[i][0].num,i));
}
sort(q.begin(),q.end(),cmp3);
int ans=-1;
for(int i=0;i<q.size();i++){
int bh=q[i].second;
int cc=1;
while(col[a[bh][cc].colu]) cc++;
ans=max(a[bh][cc].num,ans);
//cout<<ans<<"!!!!!!!!!!"<<bh<<" "<<cc<<endl;
col[a[bh][cc].colu]=true;
}
return ans;
}
int main()
{  int a1,b1;
vector<pair<int,int> >q;
while(~scanf("%d",&m)){
int ans=3e8+200;
q.resize(m*2+100);
q.push_back(make_pair(0,0));
for(int i=0;i<=m;i++)
a[i].resize(m+1);
for(int i=0;i<2*m;i++){
scanf("%d%d",&a1,&b1);
q[i+1]=(make_pair(a1,b1));

}

for(int i=1;i<=m;i++){
for(int j=m+1;j<=m*2;j++){
a[i][j-m].num=abs(q[i].first-q[j].first)+abs(q[i].second-q[j].second);
a[i][j-m].colu=j-m;

}
}
ans=min(solve(),ans);
for(int i=1+m;i<=m*2;i++){
for(int j=1;j<=m;j++){
a[i-m][j].num=abs(q[i].first-q[j].first)+abs(q[i].second-q[j].second);
a[i-m][j].colu=j;
//a[i-m][j]=Node(abs(q[i].first-q[j].first)+abs(q[i].second-q[i].second),j);
}
}
ans=min(ans,solve());
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  网络 思维