zoj 1002 最大独立集
题意
n*n的矩阵中,有空地和墙,放置机器人能攻击到垂直和水平地方(有墙则被隔绝),问最多能放多少机器人,相互之间不攻击
解题思路
最大独立集, 对于实际顶点应该是除去墙。 然后贴模板~~
View Code
#include<cstdio> #include<cstring> #define N 50 bool flag[N], a[N][N]; int ans, cnt[N], group[N], n, m, vis[N]; bool dfs( int u, int pos ){ int i, j; for( i = u+1; i <= n; i++){ if( cnt[i]+pos <= ans ) return 0; if( a[u][i] ){ // 与目前团中元素比较,取 Non-N(i) for( j = 0; j < pos; j++ ) if( !a[i][ vis[j] ] ) break; if( j == pos ){ // 若为空,则皆与 i 相邻,则此时将i加入到 最大团中 vis[pos] = i; if( dfs( i, pos+1 ) ) return 1; } } } if( pos > ans ){ for( i = 0; i < pos; i++ ) group[i] = vis[i]; // 最大团 元素 ans = pos; return 1; } return 0; } void maxclique() { ans=-1; for(int i=n;i>0;i--) { vis[0]=i; dfs(i,1); cnt[i]=ans; } } char mp[N][N]; int num[N][N]; int main(){ while( scanf("%d", &m), m ){ n = 0; memset( num, 0, sizeof(num)); memset( a, 0, sizeof(a)); for(int i = 1; i <= m; i++){ scanf("%s", mp[i]+1 ); for(int j = 1; j <= m; j++) if( mp[i][j] == '.' ) num[i][j] = ++n; } for(int i = 1; i <= m; i++) for(int j = 1; j <= m; j++){ if( mp[i][j] == 'X' ) continue; for(int k = j-1; k >= 1; k-- ) if( mp[i][k] == 'X' ) break; else a[ num[i][j] ][ num[i][k] ] = 1; for(int k = j+1; k <= m; k++ ) if( mp[i][k] == 'X' ) break; else a[ num[i][j] ][ num[i][k] ] = 1; for(int k = i-1; k >= 1; k-- ) if( mp[k][j] == 'X' ) break; else a[ num[i][j] ][ num[k][j] ] = 1; for(int k = i+1; k <= m; k++ ) if( mp[k][j] == 'X' ) break; else a[ num[i][j] ][ num[k][j] ] = 1; } for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) if( i == j ) a[i][j] = 0; else a[i][j] ^= 1; maxclique(); if( ans < 0 ) ans = 0; printf("%d\n", ans ); } }