zoukankan      html  css  js  c++  java
  • bzoj3275 Number

    Number

    Time Limit: 10 Sec Memory Limit: 128 MB

    Description

    (N)个正整数,需要从中选出一些数,使这些数的和最大。
    若两个数(a,b)同时满足以下条件,则(a,b)不能同时被选
    1:存在正整数(C),使(a*a+b*b=c*c)
    2:(gcd(a,b)=1)

    Input

    第一行一个正整数(n),表示数的个数。(n<=3000)
    第二行(n)个正整数(a_1,a_2,...a_n)

    Output

    最大的和

    Sample Input

    5
    3 4 5 6 7

    Sample Output

    22

    今天下午本来仔细的再学一下数学和其他相关知识的。。。。发现很多题都或多或少有点问题。。。。尴尬癌犯了啊~~~
    写一道网络流的题吧。
    表示我记得千钧一发。。。。一模一样有木有。。。
    复习一下网络流吧(就算省选考到我也不一定会建图啊233)

    
    #include<bits/stdc++.h>
    using namespace std;
    const int s = 0, t = 3010, maxn = 4001, INF = 0x3f3f3f3f;
    struct lpl{
    	int to, dis;
    }lin;
    int even[maxn], odd[maxn], layer[maxn];
    int n, x, cnt = -1, tot_1, tot_2;
    long long ans;
    vector<lpl> edge;
    vector<int> point[maxn]; 
    queue<int> q;
    
    inline void putit()
    {
    	scanf("%d", &n);
    	for(int i = 1; i <= n; ++i){
    		scanf("%d", &x); ans += x;
    		if(x & 1) odd[++tot_1] = x;
    		else even[++tot_2] = x;
    	}
    }
    
    inline void connect(int a, int b, int w)
    {
    	cnt++; lin.to = b; lin.dis = w; point[a].push_back(cnt); edge.push_back(lin);
    	cnt++; lin.to = a; lin.dis = 0; point[b].push_back(cnt); edge.push_back(lin);
    }
    
    inline void prepare()
    {
    	for(int i = 1; i <= tot_1; ++i) connect(s, i, odd[i]);
    	for(int i = 1; i <= tot_2; ++i) connect(i + tot_1, t, even[i]);
    }
    
    inline int gcd(int a, int b)
    {
    	if(a < b) swap(a, b);
    	return (a % b == 0) ? b : gcd(b, a % b);
    }
    
    inline bool check(int a, int b)
    {
    	if(gcd(a, b) != 1) return false;
    	long long c = sqrt((long long)a * a + b * b);
    	if(c * c == ((long long)a * a + b * b)) return true;
    	return false;
    }
    
    inline void workk()
    {
    	for(int i = 1; i <= tot_1; ++i)
    		for(int j = 1; j <= tot_2; ++j)
    			if(check(odd[i], even[j])) connect(i, j + tot_1, INF);
    }
    
    inline bool bfs()
    {
    	memset(layer, 0, sizeof(layer));
    	layer[s] = 1; q.push(s);
    	while(!q.empty()){
    		int now = q.front(); q.pop();
    		for(int i = point[now].size() - 1; i >= 0; --i){
    			lin = edge[point[now][i]];
    			if(layer[lin.to] || !lin.dis) continue;
    			layer[lin.to] = layer[now] + 1; q.push(lin.to);
    		}
    	}
    	return layer[t];
    }
    
    long long dfs(int a, int w)
    {
    	if(a == t || w == 0) return w;
    	long long ret = 0;
    	for(int i = point[a].size() - 1; i >= 0; --i){
    		int now = point[a][i];
    		if(layer[edge[now].to] != layer[a] + 1 || edge[now].dis <= 0) continue;
    		long long tmp = dfs(edge[now].to, min(edge[now].dis, w));
    		edge[now].dis -= tmp; edge[now ^ 1].dis += tmp; w -= tmp; ret += tmp;
    		if(!w) break;
    	}
    	return ret;
    }
    
    inline long long Dinic()
    {
    	long long ret = 0;
    	while(bfs()) ret += dfs(s, INF);
    	return ret;
    }
    
    int main()
    {
    	putit();
    	prepare();
    	workk();
    	cout << ans - Dinic();
    	return 0;
    }
    
    
    心如花木,向阳而生。
  • 相关阅读:
    Silverlight 4中把DataGrid数据导出Excel
    C#正则的委托和lambda表达式用法
    C#简单的写日志方法
    GAE上传失败
    asp.net后台进程做定时任务
    ASP.NET页面生命周期描述
    巴士电台新版发布
    jQuery 1.51.7一些值得注意的更新
    wxPython应用心得
    Ajax保留浏览器历史的两种解决方案(Hash&Pjax)[转]
  • 原文地址:https://www.cnblogs.com/LLppdd/p/8717863.html
Copyright © 2011-2022 走看看