http://www.lydsy.com/JudgeOnline/problem.php?id=3275
n^2暴力建图跑,二分图上dinic好(好像一点也不押韵= = 、)
把数按奇偶分成二分图,
s->奇 cap=权值
偶->t cap=权值
n^2暴力
奇->偶(不能同时选) cap=inf
最后sum-maxflow
Code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=3010;
int n;
int a[maxn];
struct edge{
int u,v,cap,flow;
edge(int _u=0,int _v=0,int _cap=0,int _flow=0):
u(_u),v(_v),cap(_cap),flow(_flow){}
};
vector<edge>edges;
vector<int>G[maxn];
int cur[maxn],vis[maxn];
void add(int u,int v,int cap){
edges.push_back(edge(u,v,cap,0));
G[u].push_back(edges.size()-1);
edges.push_back(edge(v,u,0,0));
G[v].push_back(edges.size()-1);
}
int d[maxn],s,t;
bool bfs(){
memset(vis,0,sizeof(vis));
queue<int>q;
q.push(s);vis[s]=1;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<G[u].size();i++){
edge e=edges[G[u][i]];
if(e.cap>e.flow&&!vis[e.v]){
d[e.v]=d[u]+1;
vis[e.v]=1;
q.push(e.v);
}
}
}return vis[t];
}
int dfs(int u,int a){
int flow=0,f;
if(u==t||!a)return a;
for(int &i=cur[u];i<G[u].size();i++){
edge e=edges[G[u][i]];
if(d[e.v]==d[u]+1&&(f=dfs(e.v,min(a,e.cap-e.flow)))>0){
edges[G[u][i]].flow+=f;
edges[G[u][i]^1].flow-=f;
flow+=f;a-=f;
if(!a)break;
}
}return flow;
}
int Dinic(){
int flow=0;
while(bfs()){
int x=0;
do{
flow+=x;
memset(cur,0,sizeof(cur));
}while(x=dfs(s,INT_MAX));
}return flow;
}
bool can(int a,int b){
typedef long long LL;
LL c=sqrt((LL)a*a+(LL)b*b);
return !((LL)a*a+(LL)b*b==c*c&&__gcd(a,b)==1);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
s=0;t=n+1;
for(int i=1;i<=n;i++)if(a[i]%2)add(s,i,a[i]);
for(int i=1;i<=n;i++)if(a[i]%2==0)add(i,t,a[i]);
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(a[i]%2&&a[j]%2==0)if(!can(a[i],a[j]))
add(i,j,INT_MAX);
cout<<accumulate(a+1,a+1+n,0)-Dinic()<<endl;
return 0;
}