bzoj3275: Number

来源:互联网 发布:淘宝详情页模板图 编辑:程序博客网 时间:2024/06/08 11:37

1A了,最小割233,拆点,s向i1连a[i]的边,i2向t连a[i]的边,有限制的i1与j2,j1与i2连inf的边,答案就是sum-ans/2啦!

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<queue>using namespace std;queue<int> q;const int inf=0x7f7f7f7f;int read(){    char ch=getchar();int f=0;    while(ch<'0'||ch>'9')ch=getchar();    while(ch>='0'&&ch<='9'){f=(f<<1)+(f<<3)+ch-'0';ch=getchar();}    return f;}int gcd(int x,int y){    return !y?x:gcd(y,x%y);}bool check(int x,int y){    if(gcd(x,y)!=1) return 0;    int z=x*x+y*y;    int temp=sqrt(z);    if(temp*temp!=z) return 0;     return 1;}struct node{    int from;    int to;    int next;    int w;}edge[5000005];int tot,head[10005],n,a[100005],s,t,ans,dis[10005];void add(int u,int v,int w){    edge[tot].from=u;    edge[tot].to=v;    edge[tot].w=w;    edge[tot].next=head[u];    head[u]=tot++;}bool bfs(){    memset(dis,-1,sizeof(dis));    q.push(s);    dis[s]=0;    while(!q.empty())    {        int x=q.front();        q.pop();        for(int i=head[x];i!=-1;i=edge[i].next)        {            if(dis[edge[i].to]==-1&&edge[i].w)            {                dis[edge[i].to]=dis[x]+1;                q.push(edge[i].to);            }        }    }    if(dis[t]==-1) return 0;    return 1;}int dfs(int x,int flow){    int ret=0;    if(x==t||!flow) return flow;    for(int i=head[x];i!=-1;i=edge[i].next)    {        if(dis[edge[i].to]==dis[x]+1)        {            int f=dfs(edge[i].to,min(edge[i].w,flow));            edge[i].w-=f;edge[i^1].w+=f;            ret+=f;flow-=f;            if(!flow) break;        }    }    if(!ret) dis[x]=-1;    return ret;}void dinic(){    while(bfs()) ans+=dfs(s,0x7f7f7f7f);}int main(){    memset(head,-1,sizeof(head));    n=read();    s=0,t=2*n+1;int sum=0;    for(int i=1;i<=n;i++)    {        a[i]=read();        sum+=a[i];    }    for(int i=1;i<=n;i++)    {        add(s,i,a[i]);        add(i,s,0);        add(i+n,t,a[i]);        add(t,i+n,0);    }    for(int i=1;i<=n;i++)    {        for(int j=i+1;j<=n;j++)        {            if(check(a[i],a[j]))            {                add(i,j+n,inf);                add(j+n,i,0);                add(j,i+n,inf);                add(i+n,j,0);            }        }    }    dinic();    cout<<sum-ans/2;}
原创粉丝点击