Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 20469 | Accepted: 7932 |
Description
Input
Output
Sample Input
5 4 PHPP PPHH PPPP PHPP PHHP
Sample Output
6
将相互冲突的点连边,那么该题就转化为求最大点独立集,进而求其补图的最大团。
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #define Maxn 1010 using namespace std; int adj[Maxn][Maxn]; int cq[Maxn]; int cnt[Maxn]; int ans; int n; bool dfs(int u,int tot){ if(tot>ans){ ans=tot; return true; } for(int v=u+1;v<=n;v++){ if(tot+cnt[v]<=ans) return false; if(adj[u][v]){ bool flag=true; for(int w=0;w<tot;w++) if(!adj[cq[w]][v]){ flag=false; break; } if(flag){ cq[tot]=v; if(dfs(v,tot+1)) return true; } } } return false; } void solve(){ ans=0; for(int i=n;i>0;i--){ cq[0]=i; dfs(i,1); cnt[i]=ans; } } struct point{ int x,y; point(int xx=0,int yy=0):x(xx),y(yy){} }p[Maxn]; char s[110][20]; bool check(int i,int j){ if(p[i].x==p[j].x) return abs(p[i].y-p[j].y)<=2; if(p[i].y==p[j].y) return abs(p[i].x-p[j].x)<=2; return false; } int main() { int np,mp; while(~scanf("%d%d",&np,&mp)){ n=0; for(int i=0;i<np;i++){ scanf("%s",s[i]); for(int j=0;s[i][j];j++) if(s[i][j]=='P') p[++n]=point(i,j); } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) adj[i][j]=0; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(check(i,j)) adj[i][j]=adj[j][i]=1; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i!=j) adj[i][j]^=1; solve(); printf("%d\n",ans); } return 0; }