Codeforces Round #309 (Div. 1)D. Nudist Beach 二分+bfs
2015-06-28 19:39
330 查看
题目:http://codeforces.com/contest/553/problem/D
在一个无向图中,有若干坏点,选择一个不包含坏点的集合,使得集合中p值最小的点的p值最大。一个点的p值=集合中与该点相连的点的个数 / 与改点相连的总点数.
思路:考虑到p值是0到1的实数值,可以二分这个最小值。每次判断当前pi是否可以成立,做法是bfs。首先把所有点加进集合中,把不符合情况的点从集合中删除,删除的时候会影响到其他点,所以要维护一个欲删除点的队列,也就是bfs一遍,记住更新答案。
代码:
在一个无向图中,有若干坏点,选择一个不包含坏点的集合,使得集合中p值最小的点的p值最大。一个点的p值=集合中与该点相连的点的个数 / 与改点相连的总点数.
思路:考虑到p值是0到1的实数值,可以二分这个最小值。每次判断当前pi是否可以成立,做法是bfs。首先把所有点加进集合中,把不符合情况的点从集合中删除,删除的时候会影响到其他点,所以要维护一个欲删除点的队列,也就是bfs一遍,记住更新答案。
代码:
[code]#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<vector> #include<set> using namespace std; typedef long long ll; const int N = 1e5+10; const double eps = 1e-8; vector<int> g ; int n,m,k,vis ; int kill ; set<int> ss,ans_set; set<int>::iterator it; double ans = 0; int tmp ; int ok(double p){ queue<int> q; ss.clear(); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++){ ss.insert(i); tmp[i] = g[i].size(); if(kill[i]){ vis[i] = 1; q.push(i); } } while(!q.empty()){ int wt = q.front() ; q.pop(); ss.erase(wt); for(int i=0;i<g[wt].size();i++){ int u = g[wt][i]; if(vis[u]) continue; tmp[u]--; double hc = 1.0*tmp[u]/g[u].size(); if(hc<p){ vis[u] = 1; q.push(u); } } } int fl = 1; for(it=ss.begin();it!=ss.end();it++) if(1.0*tmp[*it]/g[*it].size() < p){ fl = 0 ; break;} if(fl && ss.size()>0){ if(p>ans){ ans = p; ans_set = ss; } return 1; } return 0; } int main(){ cin >> n >> m >> k; ans_set.clear(); memset(kill,0,sizeof(kill)); for(int i=0;i<=n;i++) g[i].clear(); for(int i=1;i<=k;i++){ int x; scanf("%d",&x); kill[x] = 1; } for(int i=1;i<=m;i++){ int u,v; scanf("%d%d",&u,&v); g[u].push_back(v); g[v].push_back(u); } int co = 0; double high=1.0 , low = 0.0; while(co<40){ co++; double mid = (high + low)/2; if( ok(mid) ) low = mid; else high = mid; } if(ans_set.size()==0){ cout<<1<<endl; for(int i=1;i<=n;i++) if(!kill[i]) { cout<<i<<endl; break; } } else { cout<<ans_set.size()<<endl; for(it=ans_set.begin();it!=ans_set.end();it++) cout<<*it<<" "; cout<<endl; } return 0; }
相关文章推荐
- CSS+DIV+JQuery实际的视频汇总
- 下一步怎么办?核心网带宽必须迅猛增长!
- jbpm6 开发环境搭建
- 《征服C指针》——读书笔记(6)
- 下一步怎么办?核心网带宽必须迅猛增长!
- 程序员常去的14个顶级开发社区
- DNS
- 作业5.19
- jdbc基础 (五) 连接池与数据源:DBCP以及C3P0的使用
- equals和==比较
- unity手游《摩卡世界online》全套源码(服务端+客户端+数据库)
- 欢迎使用CSDN-markdown编辑器
- 【Android】画廊式的图片浏览器,使用HorizontalScrollView取代Gallery,OnClickListener的参数传递
- 红鱼儿
- js对象的继承
- hdu 4738 13杭州网络赛 判断无向图的桥
- C++中指针详解
- COJ883 工艺品
- uniGUI-shuiying
- 版本管理工具git的使用