您的位置:首页 > 其它

HDU 5556 最大独立集

2015-11-25 00:13 337 查看
这题主要有了中间的一些连通块的限制,不太好直接用二分图最大独立集做。考虑到图比较小,可以作补图求最大团来求解。

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <string.h>
#include <stdio.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <cassert>
#include <sstream>
using namespace std;

const int N=110;

char s

;
int id

;
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int n,m;

struct MC{
bool graph

;
int stk

,dp
,mc;
int choice
,vertex
;
void dfs(int n,int sz,int dep){
if (sz==0){
if (dep>mc){
mc=dep;
for (int i=0;i<mc;i++)
vertex[i]=choice[i];
}
return;
}
for (int i=0;i<sz;i++){
int u=stk[dep][i];
if (dep+dp[u]<=mc) return;
if (dep+sz-i<=mc) return;
choice[dep]=u;
int cnt=0;
for (int j=i+1;j<sz;j++){
int v=stk[dep][j];
if (graph[u][v])
stk[dep+1][cnt++]=v;
}
dfs(n,cnt,dep+1);
}
}
int maxClique(int n){
mc=1;
//节点从1开始标号
dp
=1;
for (int i=n-1;i>=1;i--){
int sz=0;
for (int j=i+1;j<=n;j++)
if (graph[i][j])
stk[1][sz++]=j;
choice[0]=i;
dfs(n,sz,1);
dp[i]=mc;
}
return mc;
}
void solve(int &cas) {
map<char,int> mp;
int cnt=0;
for (int i=1;i<=n;i++) {
for (int j=1;j<=m;j++) {
if (s[i][j]=='.')
id[i][j]=++cnt;
else if (mp.find(s[i][j])==mp.end())
id[i][j]=mp[s[i][j]]=++cnt;
else
id[i][j]=mp[s[i][j]];
}
}
//for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) cout<<id[i][j]<<" ";cout<<endl;
for (int i=1;i<=cnt;i++) {
for (int j=1;j<=cnt;j++) {
if (i==j) graph[i][j]=false;
graph[i][j]=true;
}
}
for (int i=1;i<=n;i++) {
for (int j=1;j<=m;j++) {
int u=id[i][j];
for (int k=0;k<4;k++) {
int ni=i+dx[k];
int nj=j+dy[k];
if (ni<=0||nj<=0||ni>n||nj>m) continue;
int v=id[ni][nj];
graph[u][v]=false;
graph[v][u]=false;
}
}
}
printf("Case #%d: %d\n",cas,maxClique(cnt));
}
}mc;

int main () {
//freopen("out.txt","r",stdin);
int T;
scanf("%d",&T);
while (T--) {
scanf("%d %d",&n,&m);
for (int i=1;i<=n;i++) {
scanf("%s",s[i]+1);
}
static int cas=1;
mc.solve(cas);
cas++;
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: