zoukankan      html  css  js  c++  java
  • LuoguP2765 魔术球问题

    LuoguP2765 魔术球问题

    首先,很难看出来这是一道网络流题.但是因为在网络流24题中,所以还是用网络流的思路

    首先考虑完全平方数的限制。

    如果(i,j)满足(i < j) 且 $i + j (为完全平方数我们就在)i - j $连一条有向边

    练完之后我们会得到这样一个图(图来自luogu题解)

    Ason6P.png

    发现这是一个DAG,而且我们将柱子的限制转化为路径条数。问题就转化成了

    LuoguP2764 最小路径覆盖问题

    然后,我们就一直加球,加到需要的路径条数大于给定的柱子数为止

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<queue>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int N = 2e5 + 3;
    const int M = 2e6 + 3;
    const int INF = 2e9;
    int n,s,t,tot = 1,top;
    vector <int> G[N];
    int pre[N],head[N],cur[N],high[N],first[N];
    bool vis[N];
    struct edge{
    	int from;
    	int to;
    	int nxt;
    	int flow;	
    }e[M];
    inline void add(int x,int y,int z){
    	e[++tot].to = y;
    	e[tot].flow = z;
    	e[tot].from = x;
    	e[tot].nxt = head[x];	
    	head[x] = tot;
    	e[++tot].to = x;
    	e[tot].flow = 0;
    	e[tot].from = y;
    	e[tot].nxt = head[y];
    	head[y] = tot; 
    }
    inline int read(){
        int v = 0,c = 1;char ch = getchar();
        while(!isdigit(ch)){
            if(ch == '-') c = -1;
            ch = getchar();	
        }
        while(isdigit(ch)){
            v = v * 10 + ch - 48;
            ch = getchar();	
        }
        return v * c;
    }
    inline bool bfs(){
    	queue <int> q;
    	for(int i = 0;i <= t;++i) high[i] = 0;
    	q.push(s);high[s] = 1;
    	while(!q.empty()){
    		int k = q.front();q.pop();
    		for(int i = head[k];i;i = e[i].nxt){
    			int y = e[i].to;
    			if(!high[y] && e[i].flow > 0)
    			high[y] = high[k] + 1,q.push(y);
    		}
    	}
    	return high[t] != 0;
    }
    inline int dfs(int x,int dis){
    	if(x == t) return dis;
    	for(int &i = cur[x];i;i = e[i].nxt){
    		int y = e[i].to;
    		if(high[y] == high[x] + 1 && e[i].flow > 0){
    			int flow = dfs(y,min(dis,e[i].flow));
    			if(flow > 0){
    				e[i].flow -= flow;
    				e[i ^ 1].flow += flow;
    				pre[x >> 1] = y >> 1;
    				return flow;	
    			}
    		}
    	}
    	return 0;
    }
    inline int dinic(){
    	int res = 0;
    	while(bfs()){
    		for(int i = 0;i <= t;++i) cur[i] = head[i];
    		while(int now = dfs(s,INF)) res += now;
    	}
    	return res;
    }
    int main(){
    	n = read();
    	int sum = 0,now = 0;
    	s = 100000 + 2,t = s + 1;
    	while(now <= n){
    		sum++;
    		add(s,sum << 1,1);
    		add(sum << 1 | 1,t,1);
    		for(int i = sqrt(sum) + 1;i * i < sum * 2;++i)
    			add((i * i - sum) << 1,sum << 1 | 1,1);	
    		int f = dinic();
    		if(!f) first[++now] = sum;
    	}
    	printf("%d
    ",sum - 1);
    	for(int i = 1;i <= n;++i){
    		if(vis[first[i]]) continue;
    		for(int j = first[i];j != 0 && j != (t >> 1);j = pre[j])
    		vis[j] = 1,printf("%d ",j);
    		puts("");
    	}
    	return 0;	
    }
    
  • 相关阅读:
    Qt QTimer定时器相关
    C#Datetime和long之间转换
    C# 把图片资源转成字节数组写入到数据库
    Qt QProcess启动和关闭外部程序
    Qt绘图
    有哪些十分惊艳的书值得推荐3
    Stack Overflow 推荐编程书单
    《编写可读代码的艺术》的读书笔记 (脑图)
    [apache spark]洞见纽约车辆事故|bluemix|apache spark
    [lean scala]|How to create a SBT project with Intellij IDEA
  • 原文地址:https://www.cnblogs.com/wyxdrqc/p/10637541.html
Copyright © 2011-2022 走看看