BZOJ 3158&3275

WA了无数次后,发现自己的板子挂了。。

#include
#define N 3010
#define M 1001000
using namespace std;
int beg[N],cop[N],dis[N];
long long a[N],b[N];
int to[M],ll[M],nex[M];
int n,len=1,S,T;
long long ans;
queue q;
int gcd(int a,int b){
    return !b?a:gcd(b,a%b);
}
inline void Add(int a,int b,int c){
    nex[++len]=cop[a],cop[a]=len,to[len]=b,ll[len]=c;
    nex[++len]=cop[b],cop[b]=len,to[len]=a,ll[len]=0;
}
int dfs(int p,int fr){
    if(p==T) return fr;
    int tot=0;
    for(int &i=beg[p];i;i=nex[i]){
        if(dis[to[i]]==dis[p]+1&&ll[i]&&fr){
            int f=dfs(to[i],min(fr,ll[i]));
            ll[i]-=f;
            ll[i^1]+=f;
            tot+=f;
            fr-=f;
        }
    }
    return tot;
}
inline bool bfs(){
    q.push(S);
    memset(dis,-1,sizeof(dis));
    dis[S]=0;
    while(!q.empty()){
        int st=q.front();q.pop();
        for(int i=cop[st];i;i=nex[i]){
            if(dis[to[i]]==-1&&ll[i]){
                q.push(to[i]);
                dis[to[i]]=dis[st]+1;
            }
        }
    }
    return dis[T]!=-1;
}
int main(){
    scanf("%d",&n);
    S=n+1,T=n+2;
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for(int i=1;i<=n;i++) scanf("%lld",&b[i]);
    for(int i=1;i<=n;i++){
        if(a[i]&1) Add(S,i,b[i]);
        else Add(i,T,b[i]);
        ans+=b[i];
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            long long w=sqrt(a[i]*a[i]+a[j]*a[j]);
            if(i!=j&&w*w==a[i]*a[i]+a[j]*a[j]&&gcd(a[i],a[j])==1&&a[i]%2&&a[j]%2==0){
                Add(i,j,1008610086);
            }
        }
    }
    int f;
    while(bfs()){
        for(int i=1;i<=T;i++) beg[i]=cop[i];
        while((f=dfs(S,1008610086))!=0) ans-=f;
    }
    printf("%lld\n",ans);
    return 0;
}

你可能感兴趣的:(最大流,bzoj,最大流,bzoj)