The Maximum Unreachable Node Set。
题意:
就是给你一个有向无环图,现在让你求出一个最大的点集,使得任意两点之间不能相互到达。
思考:
乍一看感觉像是求最大独立集,但是其实不是的,你发现答案不对。因为这是有向图,而不是二分图,所以你要建立二分图。但是建立完之后图就和原题给的图不一样了,你再求最大独立集是不对的,你已经吧题意给转化了。其实这里,求谁也不能到达谁,由于路径可以重复走,所以先求出来最大匹配,剩下的就是互不可达的。那也就是最小重复路径覆盖。
代码:
int T,n,m,k;
int va[M][M];
int dist[M][M];
int vis[N],match[N];
vector<int > e[N];
bool dfs(int now)
{
for(int i=1;i<=n;i++)
{
int spot = i;
if(vis[spot]||dist[now][spot]==0||spot==now) continue; //注意自己到自己这里也要判断
vis[spot] = 1;
if(match[spot]==0||dfs(match[spot]))
{
match[spot] = now;
return true;
}
}
return false;
}
signed main()
{
IOS;
cin>>T;
while(T--)
{
cin>>n>>m;
for(int i=1;i<=n;i++) vis[i] = match[i] = 0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i!=j) dist[i][j] = 0;
if(i==j) dist[i][j] = 1;
}
}
while(m--)
{
int a,b;
cin>>a>>b;
dist[a][b] = 1;
}
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
dist[i][j] |= (dist[i][k]&dist[k][j]);
}
}
int ans = 0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++) vis[j] = 0;
if(dfs(i)) ans++;
}
cout<<n-ans<<"\n";
}
return 0;
}
总结:
多多思考本质。