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 }