kyeremal-网络流24题T4-魔术球问题
来源:互联网 发布:charge是什么软件 编辑:程序博客网 时间:2024/05/21 09:23
原题:04-魔术球问题
分析:直接求解较难,所以考虑使用二分/枚举答案+验证的方法,二分或枚举出一个答案后,即枚举出数字的集合:A=[1,N],那么对于每一组i,j∈A,如果i<j,且i+j为完全平方数,那么建立一条从i->j的有向边,那么问题就转化为求这个图的最小点路径覆盖。
code:
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <algorithm>#include <queue>#include <vector> using namespace std; #define rep(i, l, r) for (int i = l; i <= r; i++)#define REP(i, l, r) for (int i = l; i >= r; i--)#define EPS (1e-7)#define INF 19971228#define MAXN 1000010 int n, N, first[MAXN], next[MAXN], S, T, dis[MAXN];struct tlist {int x, y, f;} a[MAXN];queue<int> q; inline int min(int a, int b) {return a<b ? a : b;}inline int max(int a, int b) {return a>b ? a : b;}inline double absD(double a, double b) {return (a > b) ? a-b : b-a;}inline bool square(int n) {return absD(sqrt(n*1.0), int(sqrt(n))) < EPS;} inline void add(int x, int y, int f) { a[++N].x = x, a[N].y = y, a[N].f = f, next[N] = first[x], first[x] = N; a[++N].x = y, a[N].y = x, a[N].f = 0, next[N] = first[y], first[y] = N;}inline void init() { N = -1; memset(next, -1, sizeof(next)); memset(first, -1, sizeof(first));} inline bool bfs() { while (!q.empty()) q.pop(); memset(dis, -1, sizeof(dis)); q.push(S); dis[S] = 0; while (!q.empty()) { int x = q.front(); q.pop(); for (int i = first[x]; ~i; i = next[i]) if (!~dis[a[i].y] && a[i].f) { dis[a[i].y] = dis[x] + 1; q.push(a[i].y); } } return ~dis[T];} inline int find(int x, int low) { int sum = 0, temp; if (x == T) return low; for (int i = first[x]; ~i; i = next[i]) if ((a[i].f) && (dis[a[i].y] == dis[x] + 1) && (temp = find(a[i].y, min(low-sum, a[i].f)))) { a[i].f -= temp; a[i^1].f += temp; sum += temp; } return sum;} inline int dinic(int begin, int end) { S = begin, T = end; int temp, ans = 0; while (bfs()) while (temp = find(S, 0x7fffffff)) ans += temp; return ans;} inline int make(int K) {init(); rep(i, 1, K) add(0, i, 1); rep(i, 1, K) add(K+i, 2*K + 1, 1); rep(i, 1, K) rep(j, i+1, K) if (square(i+j)) add(i, K+j, INF); return K - dinic(0, 2*K + 1);} int main() { // freopen("zyq.in", "r", stdin); cin >> n; int L = 1, R = 3000, mid; while ((R-L) > 1) { mid = (L + R) >> 1; if (make(mid) <= n) L = mid; else R = mid; } int out = 0; if (make(R) <= n) out = R; out = max(L, out); cout << out << endl; return 0;}
0 0
- kyeremal-网络流24题T4-魔术球问题
- kyeremal-网络流24题T1-飞行员配对方案问题
- kyeremal-网络流24题T2-太空飞行计划问题
- kyeremal-网络流24题T3-最小路径覆盖问题
- kyeremal-网络流24题T5-圆桌问题
- kyeremal-网络流24题T7-试题库问题
- 【网络流24题】魔术球问题
- 【网络流24题】魔术球问题
- 【网络流24题】魔术球问题
- [网络流24题]魔术球问题
- kyeremal-网络流24题T6-最长递增子序列问题
- 魔术球问题(网络24题,三)
- 线性规划与网络流24题 04魔术球问题
- 网络流与线性规划24题04魔术球问题
- [网络流24题 #4]魔术球问题
- [网络流24题]魔术球问题(简化版)
- 魔术球问题[网络流24题之4]
- 网络流24题之魔术球问题
- AndrewNg - 线性回归【1】梯度下降
- UIButton,UIAlertView
- (7-6)hive的set命令
- 相关
- (ASCII UTF-8 Unicode )字符编码小结
- kyeremal-网络流24题T4-魔术球问题
- 使用java程序模拟页面发送http的post请求
- 心情日记
- Android实现按A-Z字母排序和模糊查询
- uva- 1593 - Alignment of Code c++,stl练习
- 第6题
- php基本语法和数据类型、变量销毁
- usaco BarnRepair题目解答
- 注释的一般用法