博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NOIP 2010 关押罪犯
阅读量:7263 次
发布时间:2019-06-29

本文共 1904 字,大约阅读时间需要 6 分钟。

二分图判断+二分

给一堆点、边,两两之间有一个值,让分成两个集合,让内部最大边权最小。

排序+二分+二分图判定

存个二分图模板

#include <iostream>
#include <functional>
#include <algorithm>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <utility>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <limits>
#include <memory>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef long long LL;
typedef pair<int,int>pii;
const int N=2e4+5;
const int INF=0x3f3f3f3f;
int head[N],tot,n,m;
struct Edge
{
    int u,v,next;
    bool operator<(const Edge &rhs)const
    {
        return next<rhs.next;
    }
} edge[N*10],o[N*5];
void add(int u,int v)
{
    edge[tot].v=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}
int cur[N];
bool dfs(int u,int f)
{
    cur[u]=(cur[f]^1);
    for(int i=head[u]; ~i; i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==f||cur[v]==(cur[u]^1))continue;
        if(cur[v]==cur[u])return false;
        if(!dfs(v,u))return false;
    }
    return true;
}
bool judge(int x)
{
    Edge tmp;
    tmp.next=x;
    int pos=upper_bound(o+1,o+1+m,tmp)-o;
    if(pos>m)return true;
    memset(head,-1,sizeof(head)),tot=0;
    memset(cur,-1,sizeof(cur));
    int s;
    for(int i=pos; i<=m; ++i)
        add(o[i].u,o[i].v),add(o[i].v,o[i].u),s=o[i].u;
    for(int i=pos;i<=m;++i){
      int s=o[i].u;
      if(cur[s]!=-1)continue;
      cur[s]=0;
      if(!dfs(s,s))return false;
    }
    return 1;
}
int main()
{
    scanf("%d%d",&n,&m);
    if(m==0)
    {
        printf("0\n");
        return 0;
    }
    for(int i=1; i<=m; ++i)
        scanf("%d%d%d",&o[i].u,&o[i].v,&o[i].next);
    o[0].next=0;
    sort(o+1,o+1+m);
    int l=0,r=m;
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(judge(o[mid].next))r=mid;
        else l=mid+1;
    }
    printf("%d\n",o[(l+r)>>1].next);
    return 0;
}

转载于:https://www.cnblogs.com/nj-czy/p/5451296.html

你可能感兴趣的文章
神奇的“数组转指针”
查看>>
24小时从0到1开发阴阳师小程序
查看>>
CSS3动画实现3D倒计时效果
查看>>
TypeScript 爬虫
查看>>
Scrollview 和 内部 recycleview 高度固定时嵌套冲突的一种解决方法
查看>>
h5引用第三方字体库
查看>>
PHPer 面试指南-扩展阅读资源整理
查看>>
设计模式-单例模式
查看>>
package.json和package-lock.json
查看>>
pattern
查看>>
MyBatis中井号与百分号的区别
查看>>
新建一个xib
查看>>
初识HTTP
查看>>
Python安装(一)
查看>>
thinkphp 输出变量使用函数处理
查看>>
MySQL学习笔记 - 1 - 基本架构与日志两阶段提交
查看>>
编程语言对比手册(横向版)[-PHP-]
查看>>
Vue 中状态管理VueX的使用方法?
查看>>
thinkphp控制器获取参数
查看>>
Netty源码分析(七):初识ChannelPipeline
查看>>