首先注意到我们只会保护电脑到服务器的边。不回去保护电脑之间的边。原因很简单,电脑到电脑的边最终还是得接到电脑到服务器的边上去。那么我们用一个集合st表示电脑i能到的服务器的集合st[i]。考虑i的所有后继j,如果所有的j都不能到某个服务器,而i能到,那么就把i到这个服务器的边保护起来就可以了。
#include <bits/stdc++.h>
#define maxn 55
using namespace std;
int n,m,a[maxn][maxn];
long long st[maxn],dp[maxn];
long long dfs(int u)
{
if(dp[u]!=-1)
return dp[u];
dp[u]=st[u];
for(int v=0;v<n;v++)
{
if(a[u][v])
{
dp[u]|=dfs(v);
}
}
return dp[u];
}
int bitcount(long long x)
{
return x==0?0:bitcount(x>>1)+(x&1);
}
class NetworkSecurity
{
public: int secureNetwork(vector <string> clientCable, vector <string> serverCable)
{
n=clientCable.size();
m=serverCable[0].length();
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(clientCable[i][j]=='Y')
a[i][j]=1;
else
a[i][j]=0;
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(serverCable[i][j]=='Y')
st[i]|=(1LL<<j);
}
}
memset(dp,-1,sizeof(dp));
for(int i=0;i<n;i++)
{
dfs(i);
}
int ans=0;
for(int i=0;i<n;i++)
{
long long son=0;
for(int j=0;j<n;j++)
{
if(a[i][j])
son|=dp[j];
}
ans=ans+bitcount(dp[i]^son);
}
return ans;
}
};