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; }