TC SRM 696 DIV2 1000 Clicountingd2
Problem Statement
给定一个n*n的矩阵,表示一个无向图。
0:不相邻;1:相邻;?:未知.
其中'?'的关系有m个(对称的2个算一种),从而有2^m种情况,求每种情况的最大团大小之和。
n≤20,m≤20,保证矩阵合法。
Tutorial
枚举每个点集,考虑能否形成团,如果关系中有0则跳过,对于能形成团的的,考虑用到了哪些未知关系,把这个处理成集合的形式,然后用高维前缀和求一下最大值就好了。
PS:最开始想到高维前缀和时懵了一下,没有想下去,去想枚举未知关系,不知所措,导致TC首秀很失败啊==
1 #include <set> 2 #include <ctime> 3 #include <queue> 4 #include <cstdio> 5 #include <bitset> 6 #include <cctype> 7 #include <bitset> 8 #include <cstdlib> 9 #include <cassert> 10 #include <cstring> 11 #include <iostream> 12 #include <algorithm> 13 #define inf (1<<30) 14 #define INF (1ll<<62) 15 #define fi first 16 #define se second 17 #define rep(x,s,t) for(register int x=s,t_=t;x<t_;++x) 18 #define per(x,s,t) for(register int x=t-1,s_=s;x>=s_;--x) 19 #define prt(x) cout<<#x<<":"<<x<<" " 20 #define prtn(x) cout<<#x<<":"<<x<<endl 21 #define pb(x) push_back(x) 22 #define hash asfmaljkg 23 #define rank asfjhgskjf 24 #define y1 asggnja 25 #define y2 slfvm 26 using namespace std; 27 typedef long long ll; 28 typedef pair<int,int> ii; 29 const int maxn=20; 30 int n; 31 int mx[1<<maxn];// 32 int b[1<<maxn]; 33 int id[maxn][maxn]; 34 int v[maxn]; 35 int d[maxn];//相邻点 36 37 template<class T>inline void Max(T &x,T y){if(x<y)x=y;} 38 template<class T>inline void Min(T &x,T y){if(x>y)x=y;} 39 40 class Clicountingd2 { 41 public: 42 int count(vector <string> g) { 43 n=g.size(); 44 int tot=0; 45 rep(i,0,n)b[1<<i]=i; 46 rep(i,0,n)d[i]=0; 47 rep(i,0,n)v[i]=0; 48 rep(i,0,n)rep(j,0,n)id[i][j]=0; 49 50 rep(i,0,n)rep(j,0,n){ 51 if(i==j||g[i][j]=='1'||g[i][j]=='?') 52 d[i]|=1<<j; 53 if(g[i][j]=='?'){ 54 v[i]|=1<<j; 55 if(i>j)id[i][j]=id[j][i]; 56 else id[i][j]=tot++; 57 } 58 } 59 memset(mx,0,sizeof mx); 60 rep(i,0,1<<n){ 61 bool ok=true; 62 int cnt=0; 63 for(int t=i;t;t-=t&-t){ 64 int k=b[t&-t]; 65 cnt++; 66 if((d[k]&i)!=i){ 67 ok=false; 68 break; 69 } 70 } 71 if(!ok)continue; 72 int flag=0; 73 for(int t=i;t;t-=t&-t){ 74 int k=b[t&-t]; 75 for(int s=v[k]&i;s;s-=s&-s){ 76 int l=b[s&-s]; 77 flag|=1<<id[k][l]; 78 } 79 } 80 Max(mx[flag],cnt); 81 } 82 rep(i,0,tot)rep(j,0,1<<tot) 83 if(j>>i&1) 84 Max(mx[j],mx[j^(1<<i)]); 85 int ans=0; 86 rep(i,0,1<<tot) 87 ans+=mx[i]; 88 return ans; 89 } 90 };