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\n" );
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\n", binary() );
153 }
View Code
posted @ 2015-05-27 14:55  idy002  阅读(280)  评论(0编辑  收藏  举报