分宿舍
分宿舍
文件名 输入文件 输出文件 时间限制 空间限制
love.cpp love.in love.out 1s 128MB
题目描述
A 校有着神奇的住宿制度,不分男女宿舍,所有 n 个学生被统一分到两栋宿舍
楼中。作为年轻人,学生之间心生爱慕之情是很正常。我们用爱慕值来表示两名学
生之间的爱慕程度,如果两名爱慕值为 c 的学生被安排在同一宿舍楼,他们或她们
便会在一起,并造成影响力为 c 的早恋事件。
每年年末,身为政教处主任的你会将所有早恋事件按照影响力从大到小排成一
个列表,然后上报给校长。公务繁忙的校长只会去看列表中第一个事件的影响力,
如果影响很大,他会考虑撤换政教处主任。
在详细考察了 n 个学生之间的爱慕关系后,你觉得压力很大。你要合理的将学
生们分到两栋宿舍,以求产生的早恋事件影响力都比较小,以保住自己的官职。假
设只要处于同一栋宿舍楼的两个人之间有爱慕关系,他们就一定会在这年的某个时
候在一起。
那么,要怎么分配,才能让校长看到的那个早恋事件的影响力最小呢?这个最
小值是多少?
输入格式
第一行两个整数 n 和 m,分别表示学生的数目和爱慕关系的对数。
接下来 m 行,每行为 3 个正整数 ai,bi,ci,表示学生 ai 和 bi 之间有爱慕关
系,爱慕值为 ci。
数据保证 1 ≤ ai ≤ bi ≤ n,0 < ci ≤ 109,且每对爱慕关系只出现一次。
输出格式
输出一个数,为通过合理安排,校长看到的那个早恋事件的最小影响力。如果
没有发生早恋事件,输出 0。
6
样例输入
4 6
1 4 2534
2 3 3512
1 2 28351
1 3 6618
2 4 1805
3 4 12884
样例输出
3512
数据范围
对于 30% 的数据,n ≤ 15。
对于 70% 的数据,n ≤ 2000,m ≤ 50000。
对于 100% 的数据,n ≤ 20000,m ≤ 100000。
二分图匹配+二分,标准的二分匹配代码:
void dfs(int x,int color)
for(int i=0;i<g[x].size();i++){
if(!v[g[x][i]]){
dfs(g[x][i],3-color);
}
else if(v[g[x][i]]==3-color) continue;
else {
//不是二分图
}
这一题注意对于每一个点都要染色,因为可能这个图不连通。
#include<bits/stdc++.h>
using namespace std;
const int N=20005,M=1e5+7;
int n,m,v[M];
bool ok;
vector<pair<int,int> >g[N];
void dfs(int x,int color,int t){
// cout << x << ' ' << color << endl;
if(ok==0) return ;
v[x]=color;
for(int i=0;i<g[x].size();i++){
if(g[x][i].second<=t) continue;
if(v[g[x][i].first]==0){
dfs(g[x][i].first,3-color,t);
}
else if(v[g[x][i].first]==3-color) continue;
else{
ok=0;
return;
};
}
}
bool check(int t){
ok=1;
memset(v,0,sizeof v);
for(int i = 1; i <= n; i++) if(!v[i])
dfs(i,1,t);
if(ok) return true;
return false;
}
int main(){
freopen("love.in","r",stdin);//freopen("love.out","w",stdout);
scanf("%d%d",&n,&m);
int mx=0;
for(int i=1,a,b,c;i<=m;i++) {
scanf("%d%d%d",&a,&b,&c);
g[a].push_back(make_pair(b,c));
g[b].push_back(make_pair(a,c));
mx=max(mx,c);
}
int l=0,r=mx,ans;
// for(int i = 1; i <= m; i++) cout << s[i].a << ' ' << s[i].b << ' ' << s[i].c << endl;
// for(int i = 1; i <= m; i++) if(s[i].c == 26123) cout << check(i) << endl;
while(l<r){
int mid=(l+r)>>1;
if(check(mid)) {
ans=mid,r=mid;
// printf("%d\n",ans);
}
else l=mid+1;
// cout << l << ' ' << mid << ' ' << r << endl;
}
printf("%d\n",ans);
return 0;
}