#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//#define int ll
//const int inf = 1e18;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> p2;
#define rep(i, high) for (int i = 0; i < (high); i++)
#define repp(i, lo, high) for (int i = (lo); i < (high); i++)
#define repe(i, container) for (auto& i : container)
#define sz(x) ((int)(x).size())
#define all(x) begin(x), end(x)
#if _LOCAL
static int n;
static std::vector<std::vector<int>> p;
static std::vector<std::vector<int>> b;
static bool called = false;
#endif
#if _LOCAL
static void check(bool cond, std::string message) {
if (!cond) {
printf("%s\n", message.c_str());
fclose(stdout);
exit(0);
}
}
#else
static void check(bool cond, std::string message);
#endif
#if _LOCAL
void build(std::vector<std::vector<int>> _b) {
check(!called, "build is called more than once");
called = true;
check((int)_b.size() == n, "Invalid number of rows in b");
for (int i = 0; i < n; i++) {
check((int)_b[i].size() == n, "Invalid number of columns in b");
}
b = _b;
}
#else
void build(std::vector<std::vector<int>> _b);
#endif
struct UF
{
vi par;
vi size;
UF(int n) : par(n), size(n, 1)
{
rep(i, n) par[i] = i;
}
int find(int x) { return par[x] == x ? x: par[x] = find(par[x]); }
void merge(int a, int b)
{
a = find(a); b = find(b);
if (a == b) return;
par[b] = a;
size[a] += size[b];
}
};
int construct(vvi p) {
int n = p.size();
vvi ans(n,vi(n));
UF uf(n);
rep(i, n) rep(j, n)
{
if (p[i][j]) uf.merge(i, j);
}
map<int, vi> comps;
rep(i, n) comps[uf.find(i)].push_back(i);
repe(c, comps)
{
vi& comp = c.second;
if (sz(comp) == 0) continue;
int all_one = 1;
repe(a, comp)
{
repe(b, comp)
{
all_one &= p[a][b] == 1;
if (!p[a][b])
{
return 0;
}
}
}
if (all_one)
{
rep(i, sz(comp) - 1)
{
int u = comp[i];
int v = comp[i + 1];
ans[u][v] = 1;
ans[v][u] = 1;
}
}
else
{
vi cycle;
map<int, vi> leafs;
auto count_ones = [&](int x)
{
int ret = 0;
repe(b, comp)
{
if (b == x) continue;
ret += p[x][b] == 1;
}
return ret;
};
repe(a, comp)
{
int num_ones = count_ones(a);
if (num_ones == 0) // part of cycle, no leaves
{
cycle.push_back(a);
}
else if (num_ones == 1) // leaf
{
int ng;
repe(b, comp) if (b != a) if (p[a][b] == 1) ng = b;
if (count_ones(ng)==1&&a<ng)
{
cycle.push_back(a);
}
else
{
leafs[ng].push_back(a);
}
}
else // part of cycle, owns many leafs
{
cycle.push_back(a);
}
}
if (sz(cycle) <= 2)
{
return 0;
}
rep(i, sz(cycle))
{
int u = cycle[i];
int v = cycle[(i + 1) % sz(cycle)];
ans[u][v] = 1;
ans[v][u] = 1;
}
repe(h, leafs)
{
repe(l, h.second)
{
ans[h.first][l] = 1;
ans[l][h.first] = 1;
}
}
}
}
build(ans);
return 1;
}
#if _LOCAL
int main() {
cin >> n;
p.resize(n);
for (int i = 0; i < n; i++) {
p[i].resize(n);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> p[i][j];
}
}
int possible = construct(p);
check(possible == 0 || possible == 1, "Invalid return value of construct");
if (possible == 1) {
check(called, "construct returned 1 without calling build");
}
else {
check(!called, "construct called build but returned 0");
}
printf("%d\n", possible);
if (possible == 1) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (j) {
printf(" ");
}
printf("%d", b[i][j]);
}
printf("\n");
}
}
fclose(stdout);
}
#endif
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |