博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【NOIP2010】关押罪犯prison
阅读量:5244 次
发布时间:2019-06-14

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

【问题描述】

    有两个监狱,要关押n个罪犯。两个罪犯直接可能会有怨气值,若这两人在同一个监狱,则会爆发一个事件,事件的影响力等于两个罪犯的怨气值。答案等于所有事件的影响力的最大值,要使答案最小。有m对罪犯有怨气值。

    n≤20000,m≤100000

【分析】

    曾经有大牛说过,一般题目求“最小值的最大值”或“最大值的最小值”的话,都可以用二分做。这句话真心很好用啊!

    二分答案,然后构造二分图,即怨气值大于答案的罪犯需在不同监狱,若可以构造则修改右边界,否则修改左边界。总时间复杂度O(n log c)。

【代码】

    PS:懒得写链表直接用vector存边不要介意。

#include 
#include
#include
#include
#include
using namespace std;struct edge{ int y,v; edge(const int a,const int b):y(a),v(b){}};vector
e[20010];int a[20010];bool p[20010];int n,m;int Max;bool dfs(int x){ p[x] = true; for (int i = 0;i < e[x].size();i ++) { int j = e[x][i].y,v = e[x][i].v; if (v <= Max) continue; if (p[j]) { if (a[x] + a[j] != 1) { return false; } } else { a[j] = 1 - a[x]; if (!dfs(j)) return false; } } return true;}bool check(int k){ Max = k; memset(a,0,sizeof(a)); memset(p,0,sizeof(p)); for (int i = 1;i <= n;i ++) if (!p[i]) if (!dfs(i)) return false; return true;}int main(){ freopen("prison.in","r",stdin); freopen("prison.out","w",stdout); scanf("%d %d",&n,&m); for (int i = 1;i <= m;i ++) { int x,y,v; scanf("%d %d %d",&x,&y,&v); e[x].push_back(edge(y,v)); e[y].push_back(edge(x,v)); } int l = 1,r = 0x3f3f3f3f; while (r > l ) { int mid = (l + r) / 2; if (check(mid)) r = mid; else l = mid + 1; } cout << l; fclose(stdin);fclose(stdout);}

 

  

转载于:https://www.cnblogs.com/N-C-Derek/archive/2012/10/14/2723362.html

你可能感兴趣的文章
RQNOJ八月赛
查看>>
前端各种mate积累
查看>>
jQuery 1.7 发布了
查看>>
Python(软件目录结构规范)
查看>>
Windows多线程入门のCreateThread与_beginthreadex本质区别(转)
查看>>
Nginx配置文件(nginx.conf)配置详解1
查看>>
linux php编译安装
查看>>
name phone email正则表达式
查看>>
「Unity」委托 将方法作为参数传递
查看>>
重置GNOME-TERMINAL
查看>>
redis哨兵集群、docker入门
查看>>
hihoCoder 1233 : Boxes(盒子)
查看>>
oracle中anyData数据类型的使用实例
查看>>
软件测试——性能测试总结
查看>>
12.4站立会议
查看>>
客户端访问浏览器的流程
查看>>
codeforces水题100道 第二十二题 Codeforces Beta Round #89 (Div. 2) A. String Task (strings)
查看>>
c++||template
查看>>
[BZOJ 5323][Jxoi2018]游戏
查看>>
编程面试的10大算法概念汇总
查看>>