zoukankan      html  css  js  c++  java
  • bzoj 3158 千钧一发(最小割)

    3158: 千钧一发

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 767  Solved: 290
    [Submit][Status][Discuss]

    Description

     

    Input

    第一行一个正整数N。

    第二行共包括N个正整数,第 个正整数表示Ai。

    第三行共包括N个正整数,第 个正整数表示Bi。

    Output

    共一行,包括一个正整数,表示在合法的选择条件下,可以获得的能量值总和的最大值。

    Sample Input



    4
    3 4 5 12
    9 8 30 9

    Sample Output


    39

    HINT



    1<=N<=1000,1<=Ai,Bi<=10^6

    Source

    【思路】

           最小割。

           注意到ai,aj同时是偶数或同时是奇数时必定可以被同时选出:

           1 同为偶数满足条件2

           2 同为奇数时有(2a+1)^2+(2b+1)^2=2(2a^2+2b^2+2a+2b+1),所以满足条件1。

           以此构二分图,设奇数为X结点偶数为Y结点,如果不满足任一条件则连边(Xi,Yj,INF),同时相应连S到X,Y到T的边容量为b,那么答案就是一个二分图最小割,即通过删除一些结点使得满足剩下的结点不相邻且有b之和最小。

    【代码】

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<queue>
      4 #include<cstring>
      5 #include<iostream>
      6 using namespace std;
      7 
      8 typedef long long LL;
      9 const int maxn = 4000+10;
     10 const int INF = 1e9+1e9;
     11 
     12 struct Edge{  int u,v,cap,flow;
     13 }; 
     14 
     15 struct Dinic {
     16     int n,m,s,t;
     17     int d[maxn],cur[maxn],vis[maxn];
     18     vector<int> G[maxn];
     19     vector<Edge> es;
     20     
     21     void init(int n) {
     22         this->n=n;
     23         for(int i=0;i<n;i++) G[i].clear();
     24         es.clear();
     25     }
     26     void AddEdge(int u,int v,int cap) {
     27         es.push_back((Edge){u,v,cap,0});
     28         es.push_back((Edge){v,u,0,0});
     29         m=es.size();
     30         G[u].push_back(m-2);
     31         G[v].push_back(m-1);
     32     }
     33     bool bfs() {
     34         queue<int> q;
     35         memset(vis,0,sizeof(vis));
     36         vis[s]=1; d[s]=0; q.push(s);
     37         while(!q.empty())    {
     38             int u=q.front(); q.pop();
     39             for(int i=0;i<G[u].size();i++) {
     40                 Edge &e=es[G[u][i]];
     41                 int v=e.v;
     42                 if(!vis[v] && e.cap>e.flow) {
     43                     vis[v]=1;
     44                     d[v]=d[u]+1;
     45                     q.push(v);
     46                 }
     47             }
     48         }
     49         return vis[t];
     50     }
     51     int dfs(int u,int a) {
     52         if(u==t || a==0) return a;
     53         int f,flow=0;
     54         for(int& i=cur[u];i<G[u].size();i++) {
     55             Edge& e=es[G[u][i]];
     56             int v=e.v;
     57             if(d[v]==d[u]+1 && (f=dfs(v,min(a,e.cap-e.flow)))>0) {
     58                 e.flow+=f;
     59                 es[G[u][i]^1].flow-=f;
     60                 flow+=f , a-=f;
     61                 if(!a) break;
     62             }
     63         }
     64         return flow;
     65     }
     66     int maxflow(int s,int t) {
     67         this->s=s , this->t=t;
     68         int flow=0;
     69         while(bfs()) {
     70             memset(cur,0,sizeof(cur));
     71             flow+=dfs(s,INF);
     72         }
     73         return flow;
     74     }
     75 } dc;
     76 
     77 int n;
     78 int a[maxn],b[maxn];
     79 
     80 bool issqr(LL x) { return sqrt(x)*sqrt(x) == x;
     81 }
     82 int gcd(int x,int y) {
     83     return y==0? x:gcd(y,x%y);
     84 }
     85 bool jud(LL x,LL y) {
     86     LL t=x*x+y*y , sq=sqrt(t);
     87     if(sq*sq!=t) return 1;
     88     if(gcd(x,y)>1) return 1;
     89     return 0;
     90 }
     91 
     92 int main() {
     93     scanf("%d",&n);
     94     dc.init(n+2);
     95     int s=n,t=s+1;
     96     int ans=0;
     97     for(int i=0;i<n;i++) scanf("%d",&a[i]);
     98     for(int i=0;i<n;i++) scanf("%d",&b[i]) , ans+=b[i];
     99     for(int i=0;i<n;i++)
    100         if((a[i]&1)) dc.AddEdge(s,i,b[i]);
    101         else dc.AddEdge(i,t,b[i]);
    102     for(int i=0;i<n;i++)  for(int j=0;j<n;j++)
    103         if((a[i]&1) && (a[j]&1)==0)
    104             if(!jud(a[i],a[j]))  dc.AddEdge(i,j,INF);
    105     ans-=dc.maxflow(s,t);
    106     printf("%d",ans);
    107     return 0;
    108 }
  • 相关阅读:
    前端必备工具-IETest
    mysql_fetch_assoc 跟mysql_fetch_array 有什么区别?
    如何将Emmet安装到到 Sublime text 3?
    如何将Emmet(ZenCoding)安装到到Dreamweaver8?
    前端必备工具-Emmet (Zen Coding)
    前端必备工具-Sublime Text 2
    开店资源分享
    开店充值其实可以很便宜
    简单Gif制作
    项目笔记:导入功能
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5078060.html
Copyright © 2011-2022 走看看