zoukankan      html  css  js  c++  java
  • bzoj 3275 最小割

    给你一堆东西,叫你选一些东西出来,使得价值最大,要求选出的东西集合中的任意a,b满足性质p。

    可以考虑:

      1、拟阵?

      2、二分图?

    这道题由于数学硬伤,不知道不存在两条直角边是奇数,斜边是整数的直角三角形。

    证明是:

      对于奇数a: a*a = 1 mod 4

      对于偶数a: a*a = 0 mod 4

      所以对于两个奇数a,b: a*a+b*b = 2 mod 4

      不存在整数c使得: a*a+b*b = c*c mod 4

      1 /**************************************************************
      2     Problem: 3275
      3     User: idy002
      4     Language: C++
      5     Result: Accepted
      6     Time:3616 ms
      7     Memory:1176 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <cmath>
     12 #include <cstring>
     13 #include <vector>
     14 #define min(a,b) ((a)<(b)?(a):(b))
     15 #define oo 0x3f3f3f3f
     16 #define N 6010
     17 using namespace std;
     18  
     19 typedef long long dnt;
     20 struct Edge {
     21     int u, v, f;
     22     Edge( int u, int v, int f ):u(u),v(v),f(f){}
     23 };
     24 struct Dinic {
     25     int src, dst;
     26     vector<Edge> edge;
     27     vector<int> g[N];
     28     int dep[N], cur[N], qu[N], bg, ed;
     29     void init( int src, int dst ) {
     30         this->src = src;
     31         this->dst = dst;
     32     }
     33     void adde( int u, int v, int f ) {
     34         g[u].push_back( edge.size() );
     35         edge.push_back( Edge(u,v,f) );
     36         g[v].push_back( edge.size() );
     37         edge.push_back( Edge(v,u,0) );
     38     }
     39     bool bfs() {
     40         memset( dep, 0, sizeof(dep) );
     41         qu[bg=ed=1] = src;
     42         dep[src] = 1;
     43         while( bg<=ed ) {
     44             int u=qu[bg++];
     45             for( int t=0; t<g[u].size(); t++ ) {
     46                 Edge &e = edge[g[u][t]];
     47                 if( e.f && !dep[e.v] ) {
     48                     dep[e.v] = dep[e.u] + 1;
     49                     qu[++ed] = e.v;
     50                 }
     51             }
     52         }
     53         return dep[dst];
     54     }
     55     int dfs( int u, int a ) {
     56         if( u==dst || a==0 ) return a;
     57         int remain=a, past=0, na;
     58         for( int &t=cur[u]; t<g[u].size(); t++ ) {
     59             Edge &e=edge[g[u][t]];
     60             Edge &ve=edge[g[u][t]^1];
     61             if( e.f && dep[e.v]==dep[e.u]+1 && (na=dfs(e.v,min(remain,e.f))) ) {
     62                 remain -= na;
     63                 past += na;
     64                 e.f -= na;
     65                 ve.f += na;
     66                 if( !remain ) break;
     67             }
     68         }
     69         return past;
     70     }
     71     int maxflow() {
     72         int rt=0;
     73         while( bfs() ) {
     74             memset( cur, 0, sizeof(cur) );
     75             rt += dfs(src,oo);
     76         }
     77         return rt;
     78     }
     79 }D;
     80  
     81 int n; 
     82 int src, dst;
     83 int aa[N], sum;
     84 int gcd( int a, int b ) {
     85     return b ? gcd(b,a%b) : a;
     86 }
     87 bool ok( int a, int b ) {
     88     if( gcd(a,b)!=1 ) return false;
     89     dnt cc = (dnt)a*a + (dnt)b*b;
     90     dnt c = (dnt)sqrt(cc);
     91     if( c*c!=cc && (c+1)*(c+1)!=cc ) return false;
     92     return true;
     93 }
     94 int main() {
     95     scanf( "%d", &n );
     96     src = n+1, dst = n+2;
     97     D.init( src, dst );
     98     for( int i=1; i<=n; i++ ) {
     99         scanf( "%d", aa+i );
    100         sum += aa[i];
    101         if( aa[i]&1 ) 
    102             D.adde( src, i, aa[i] );
    103         else
    104             D.adde( i, dst, aa[i] );
    105     }
    106     for( int i=1; i<=n; i++ ) {
    107         if( !(aa[i]&1) ) continue;
    108         for( int j=1; j<=n; j++ ) {
    109             if( aa[j]&1 ) continue;
    110             if( !ok(aa[i],aa[j]) ) continue;
    111             D.adde( i, j, oo );
    112         }
    113     }
    114     printf( "%d
    ", sum-D.maxflow() );
    115 }
    View Code
  • 相关阅读:
    java socket编程
    http协议之request
    Javaweb---Servlet过滤器
    Android -- startActivityForResult-------&&&----setResult
    javaWeb---文件上传(commons-FileUpload组件)
    如何人没有十根手指,那么人类使用的进制还是10进制吗?
    linux运维、架构之路-MySQL日志(三)
    linux运维、架构之路-xtrabackup
    linux运维、架构之路-MySQL(二)
    SDN第三次作业
  • 原文地址:https://www.cnblogs.com/idy002/p/4526388.html
Copyright © 2011-2022 走看看