• BZOJ 3275 Number


    最小割。

    网络流不要写错。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #define maxn 5050
    #define maxv 20050
    #define maxe 400050
    #define inf 1000000007
    using namespace std;
    int n,a[maxn],nume=1,g[maxv],s,t,dis[maxv];
    queue <int> q;
    struct edge
    {
    int v,f,nxt;
    }e[maxe];
    void addedge(int u,int v,int f)
    {
    e[++nume].v=v;
    e[nume].f=f;
    e[nume].nxt=g[u];
    g[u]=nume;
    e[++nume].v=u;
    e[nume].f=0;
    e[nume].nxt=g[v];
    g[v]=nume;
    }
    int gcd(int a,int b)
    {
    if (b==0) return a;
    return gcd(b,a%b);
    }
    bool judge(int x,int y)
    {
    int nowx=a[x],nowy=a[y];
    int ans=nowx*nowx+nowy*nowy;
    ans=sqrt(ans);
    if ((ans*ans==nowx*nowx+nowy*nowy) && (gcd(nowx,nowy)==1))
    return true;
    return false;
    }
    bool bfs()
    {
    queue <int> q;
    memset(dis,-1,sizeof(dis));
    int vis[maxv];
    memset(vis,0,sizeof(vis));
    vis[0]=1;
    q.push(0);
    while (!q.empty())
    {
    int head=q.front();
    q.pop();
    for (int i=g[head];i;i=e[i].nxt)
    {
    if ((e[i].f) && (vis[e[i].v]==0))
    {
    q.push(e[i].v);
    dis[e[i].v]=dis[head]+1;
    vis[e[i].v]=1;
    }
    }
    }
    if (dis[t]==-1) return false;
    return true;
    }
    int dinic(int x,int low)
    {
    if (x==t)
    return low;
    else
    {
    int ret=0;
    for (int i=g[x];low && i;i=e[i].nxt)
    {
    if (e[i].f && dis[e[i].v]==dis[x]+1)
    {
    int dd=dinic(e[i].v,min(e[i].f,low));
    e[i].f=e[i].f-dd;
    e[i^1].f=e[i^1].f+dd;
    low=low-dd;
    ret=ret+dd;
    }
    }
    if (ret==0) dis[x]=-1;
    return ret;
    }
    }
    int main()
    {
    int sum=0;
    scanf("%d",&n);
    s=0;t=2*n+1;
    for (int i=1;i<=n;i++)
    {
    scanf("%d",&a[i]);
    addedge(s,i,a[i]);
    addedge(n+i,t,a[i]);
    sum=sum+a[i];
    }
    for (int i=1;i<=n;i++)
    for (int j=i+1;j<=n;j++)
    {
    if (judge(i,j)==true)
    {
    addedge(i,n+j,inf);
    addedge(j,n+i,inf);
    }
    }
    int min_cut=0;
    while (bfs()==true)
    min_cut=min_cut+dinic(s,inf);
    printf("%d ",sum-min_cut/2);
    return 0;
    }

  • 相关阅读:
    Winsock 2 入门指南
    Winsock 2 入门指南
    [手游新项目历程]-40-linux环境实现C/C++程序崩溃退出时打印栈信息
    1月下旬解题
    poj1226,poj3080
    poj3666
    poj3067
    poj12月其他题解(未完)
    poj1823,3667
    poj2352
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5266832.html
Copyright © 2020-2023  润新知