本萌新最开始不会这道题,看了半天,只感觉有规律,但是具体想法和实现无法却无法构思出来。所以,求教了学长,学长说,可以用集合来代替图论,以便解决这道题(本萌新刚刚入门,还不知道什么是图论)。这里,还专门用到了一个我为了这道题新学的stl容器——set。
在这里感谢大佬的题解codeforces Pinely Round 1 div1+2 A~C - 知乎
但大佬的题解有一点小瑕疵,那重复的两个for,只用开一个就行了。
题意如下:
给定一个n行n列的二元矩阵b(该矩阵的所有元素都为0或1)。
需要构造n个集合A1,A2,…,An,满足以下条件:
每个集合都是非空的,由1到n之间的不同整数组成。
所有集合都是不同的。
对于满足1≤i,j≤n, bi,j=1的所有对(i,j),当且仅当Ai⊊Aj。换句话说,如果Ai是Aj的一个固有子集,bi j为1,否则为0。
如果X是Y的非空子集,且X≠Y,则集合X是集合Y的固有子集。
可以保证对于这个问题中的所有测试用例,都存在这样的n个集合。注意,这并不意味着所有可能的输入都存在这样的n个集合。
如果有多个解,您可以输出其中任何一个。
(我是不会告诉你我是想偷个懒还想水个文章长度才把题目的翻译cv下来的,反正你也不会看到这里)
大佬的题解已经很详细了,这里直接上代码:
#include<stdio.h>
#include<iostream>
#include<set>
#include<math.h>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
char s[2000][2000];
int main(){
int t;
cin>>t;
while(t--){
set<int>hh[2000];
int n;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>s[i][j];
}
hh[i].insert(i);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(s[i][j]=='1'){
for(auto t:hh[i]){
hh[j].insert(t);
}
}
}
}
for(int i=1;i<=n;i++){
cout<<hh[i].size()<<" ";
for(auto t:hh[i]){
cout<<t<<" ";
}
cout<<"\n";
}
}
}