zoukankan      html  css  js  c++  java
  • bzoj 1312 最大密度子图

    晕,m=0是要输出1(弄的我还找管理员要数据,但明显题意是叫我们输出0呀)

    最大密度子图,把边转换成点,然后二分答案,跑最大权闭合子图判定是否可行。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <vector>
      4 #include <algorithm>
      5 #define N 1110
      6 #define oo 0x3f3f3f3f
      7 using namespace std;
      8 
      9 struct Edge {
     10     int u, v, f;
     11     Edge( int u, int v, int f ):u(u),v(v),f(f){}
     12 };
     13 int gcd( int a, int b ) {
     14     return b?gcd(b,a%b):a;
     15 }
     16 struct Pair {
     17     int a, b;
     18     Pair( int aa, int bb ) {
     19         int cd = gcd(aa,bb);
     20         a=aa/cd;
     21         b=bb/cd;
     22     }
     23     bool operator<( const Pair &o ) const {
     24         return a*o.b < o.a*b;
     25     }
     26     bool operator==( const Pair &o ) const {
     27         return a*o.b==o.a*b;
     28     }
     29 };
     30 int n, m;
     31 vector<Edge> edge;
     32 vector<int> g[N];
     33 vector<Pair> prs;
     34 int dep[N], cur[N], qu[N], bg, ed;
     35 int uu[N], vv[N], idx[N], src, dst, idc;
     36 bool vis[N];
     37 
     38 void init() {
     39     for( int i=1; i<=dst; i++ )
     40         g[i].clear();
     41     edge.clear();
     42 }
     43 void adde( int u, int v, int f ) {
     44     g[u].push_back( edge.size() );
     45     edge.push_back( Edge(u,v,f) );
     46     g[v].push_back( edge.size() );
     47     edge.push_back( Edge(v,u,0) );
     48 }
     49 bool bfs() {
     50     memset( dep, 0, sizeof(dep) );
     51     qu[bg=ed=1] = src;
     52     dep[src] = 1;
     53     while( bg<=ed ) {
     54         int u=qu[bg++];
     55         for( int t=0; t<g[u].size(); t++ ) {
     56             Edge &e=edge[g[u][t]];
     57             if( e.f && !dep[e.v] ) {
     58                 dep[e.v]=dep[e.u]+1;
     59                 qu[++ed] = e.v;
     60             }
     61         }
     62     }
     63     return dep[dst];
     64 }
     65 int dfs( int u, int a ) {
     66     if( u==dst || a==0 ) return a;
     67     int remain=a, past=0, na;
     68     for( int &t=cur[u]; t<g[u].size(); t++ ) {
     69         Edge &e=edge[g[u][t]];
     70         Edge &ve=edge[g[u][t]^1];
     71         if( e.f && dep[e.v]==dep[e.u]+1 && (na=dfs(e.v,min(e.f,remain))) ) {
     72             remain -= na;
     73             past += na;
     74             e.f -= na;
     75             ve.f += na;
     76             if( !remain ) break;
     77         }
     78     }
     79     return past;
     80 }
     81 int maxflow() {
     82     int flow = 0;
     83     while( bfs() ) {
     84         memset( cur, 0, sizeof(cur) );
     85         flow += dfs(src,oo);
     86     }
     87     return flow;
     88 }
     89 void makeid() {
     90     src = n+m+1;
     91     dst = src+1;
     92     idc = n;
     93     for( int i=1; i<=m; i++ ) idx[i] = ++idc;
     94 }
     95 void rebuild( int a, int b ) {
     96     init();
     97     for( int i=1; i<=m; i++ ) {
     98         adde( src, idx[i], b );
     99         adde( idx[i], uu[i], oo );
    100         adde( idx[i], vv[i], oo );
    101     }
    102     for( int i=1; i<=n; i++ ) 
    103         adde( i, dst, a );
    104 }
    105 bool ok( int a, int b ) {
    106     rebuild(a,b);
    107     return m*b-maxflow() > 0;
    108 }
    109 int calc() { 
    110     int cnt = 0;
    111     qu[bg=ed=1] = dst;
    112     vis[dst] = true;
    113     while( bg<=ed ) {
    114         int u=qu[bg++];
    115         for( int t=0; t<g[u].size(); t++ ) {
    116             Edge &e = edge[g[u][t]^1];
    117             if( e.f && !vis[e.u] ) {
    118                 vis[e.u] = true;
    119                 cnt += 1<=e.u&&e.u<=n;
    120                 qu[++ed] = e.u;
    121             }
    122         }
    123     }
    124     return n-cnt;
    125 }
    126 int binary() {
    127     for( int a=0; a<=m; a++ )
    128         for( int b=1; b<=n; b++ )
    129             prs.push_back( Pair(a,b) );
    130     sort( prs.begin(), prs.end() );
    131     prs.erase( unique(prs.begin(),prs.end()), prs.end() );
    132     int lf=0, rg=prs.size()-1;
    133     while( lf<rg ) {
    134         int mid = (lf+rg)>>1;
    135         if( ok(prs[mid].a,prs[mid].b) )
    136             lf=mid+1;
    137         else
    138             rg=mid;
    139     }
    140     ok(prs[lf].a,prs[lf].b);
    141     return calc();
    142 }
    143 int main() {
    144     scanf( "%d%d", &n, &m );
    145     if( m==0 ) {
    146         printf( "1
    " );
    147         return 0;
    148     }
    149     for( int i=1; i<=m; i++ ) 
    150         scanf( "%d%d", uu+i, vv+i );
    151     makeid();
    152     printf( "%d
    ", binary() );
    153 }
    View Code
  • 相关阅读:
    Java多线程在JavaWeb中的应用
    hibernate,spring,struts的流程以及使用理由
    hibernate如何实现持久化
    ibatis与hibernate有什么区别
    关于导出pdf的例子
    BusyBox
    Android中如何查看内存
    使用PopupWindow实现Menu功能
    ScrollView原理
    eclipse 代码提示时闪退问题
  • 原文地址:https://www.cnblogs.com/idy002/p/4533463.html
Copyright © 2011-2022 走看看