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;	
    }
    
  • 相关阅读:
    There is an overlap in the region chain修复
    There is an overlap in the region chain
    region xx not deployed on any region server
    python 中的re模块,正则表达式
    TCP粘包问题解析与解决
    yield from
    Git push提交时报错Permission denied(publickey)...Please make sure you have the correct access rights and the repository exists.
    mysql 中Varchar 与char的区别
    Mysql 字符集及排序规则
    请实现一个装饰器,限制该函数被调用的频率,如10秒一次
  • 原文地址:https://www.cnblogs.com/wyxdrqc/p/10637541.html
Copyright © 2011-2022 走看看