QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#576916 | #9319. Bull Farm | yzj123 | WA | 0ms | 15920kb | C++14 | 5.4kb | 2024-09-19 23:21:00 | 2024-09-19 23:21:01 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
int read()
{
int res = 0, bj = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') bj = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
return res * bj;
}
const int MAXN = 4005, MAXM = 1e6 + 5;
int tt, T;
int n, m, q; //n个牛棚, m个按钮
char s[MAXM];
struct Que {
int a, b, c;
int ans;
int id;
}que[MAXM];
int t[MAXN][MAXN];
bitset<MAXN> f[MAXN];
struct Edge {
int x, y;
}e1[MAXN * MAXN], e2[MAXN * MAXN]; //e2是temp数组
//e1保存的原图的边
vector<int> g[MAXN]; //染色图的边
int cnt1, cnt2;
vector<int> pos[MAXN]; //第i种染色对应的点
int in[MAXN]; //节点入度
int dfn[MAXN], low[MAXN], inx;
int stk[MAXN], top;
int vis[MAXN];
int scc, col[MAXN];
void tarjan(int u)
{
// cout << "u:" << u << "\n";
dfn[u] = low[u] = ++inx;
stk[++top] = u;
vis[u] = 1;
for (int v : g[u])
{
// cout << "v:" << v << "\n";
if (!dfn[v])
{
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if (vis[v]) low[u] = min(low[u], dfn[v]);
}
if (dfn[u] == low[u])
{
scc++;
int t;
do {
t = stk[top--];
vis[t] = 0;
for (int x : pos[t]) col[x] = scc;
} while (t != u);
}
}
void work(int K) //第K个按钮
{
// cout << "K:" << K << "---------------------------------\n";
//重置e1数组
for (int i = 1; i <= n; i++) in[i] = 0;
for (int i = 1; i <= n; i++) in[t[K][i]]++;
for (int i = 1; i <= n; i++)
if (in[i] >= 3) return; //入度>=3不符合条件
int sum2 = 0, p = 0; //入度为2的节点个数
for (int i = 1; i <= n; i++)
if (in[i] == 2) sum2++, p = i;
if (sum2 >= 2) return;
for (int i = 1; i <= cnt2; i++) e1[i] = e2[i];
cnt1 = cnt2;
cnt2 = 0;
if (sum2 == 1)
{
// cout << "task1\n";
int x, y;
for (int i = 1; i <= n; i++)
{
if (t[K][i] == p && in[i] > 0) x = i;
if (t[K][i] == p && in[i] == 0) y = i;
}
e1[++cnt1] = (Edge){x, y};
}
else
{
// cout << "task2\n";
for (int i = 1; i <= n; i++)
{
int x = i, y = t[K][i];
e1[++cnt1] = (Edge){x, y};
}
}
int last_scc = scc;
for (int i = 1; i <= last_scc; i++) g[i].clear();
cout << "cnt1:" << cnt1 << "\n";
if (T == 400) return;
for (int i = 1; i <= cnt1; i++)
{
int x = e1[i].x, y = e1[i].y;
// cout << "xy:" << x << " " << y << "\n";
if (col[x] != col[y])
{
// cout << "edge:" << col[x] << " " << col[y] << "\n";
g[col[x]].push_back(col[y]);
}
}
//tarjan清空
for (int i = 1; i <= last_scc; i++)
{
dfn[i] = low[i] = 0;
vis[i] = 0;
col[i] = 0;
}
inx = top = scc = 0;
for (int i = 1; i <= last_scc; i++)
if (!dfn[i]) tarjan(i);
// cout << "col:";
// for (int i = 1; i <= n; i++) cout << col[i] << " ";
// cout << "\n";
//更新pos数组
for (int i = 1; i <= last_scc; i++) pos[i].clear();
for (int i = 1; i <= n; i++) pos[col[i]].push_back(i);
//更新g数组为topsort数组
for (int i = 1; i <= last_scc; i++) g[i].clear();
map<pair<int, int>, int> ma;
for (int i = 1; i <= cnt1; i++)
{
int x = e1[i].x, y = e1[i].y;
if (col[x] != col[y])
{
if (ma[make_pair(col[x], col[y])] == 1) continue;
g[col[y]].push_back(col[x]);
ma[make_pair(col[x], col[y])] = 1;
e2[++cnt2] = (Edge){x, y};
}
}
for (int i = 1; i <= scc; i++) in[i] = 0; //in数组清空
for (int i = 1; i <= scc; i++) f[i].reset();
for (int u = 1; u <= scc; u++)
for (int v : g[u]) in[v]++;
queue<int> q;
for (int i = 1; i <= scc; i++)
{
f[i].set(i);
if (in[i] == 0) q.push(i);
}
while (q.size())
{
int u = q.front();
q.pop();
for (int v : g[u])
{
f[v] |= f[u];
in[v]--;
if (in[v] == 0) q.push(v);
}
}
// cout << "f:\n";
// for (int i = 1; i <= scc; i++)
// {
// for (int j = 1; j <= scc; j++) cout << f[i][j] << " ";
// cout << "\n";
// }
}
void solve()
{
// if (tt == 399) exit(0);
n = read(), m = read(), q = read();
for (int i = 1; i <= m; i++)
{
scanf("%s", s + 1);
int len = strlen(s + 1);
for (int j = 1; j <= len; j += 2)
{
int x = s[j] - 48, y = s[j + 1] - 48;
t[i][(j + 1) / 2] = x * 50 + y;
}
}
// cout << "t:\n";
// for (int i = 1; i <= m; i++)
// {
// for (int j = 1; j <= n; j++) cout << t[i][j] << " ";
// cout << "\n";
// }
for (int i = 1; i <= q; i++)
{
que[i].id = i;
scanf("%s", s + 1);
int x, y;
x = s[1] - 48, y = s[2] - 48;
que[i].a = x * 50 + y;
x = s[3] - 48, y = s[4] - 48;
que[i].b = x * 50 + y;
x = s[5] - 48, y = s[6] - 48;
que[i].c = x * 50 + y;
}
sort(que + 1, que + q + 1, [](Que A, Que B) {
return A.c < B.c;
});
scc = n;
for (int i = 1; i <= n; i++) pos[i].clear();
for (int i = 1; i <= n; i++)
{
pos[i].push_back(i);
col[i] = i;
f[i].set(i);
}
cnt1 = cnt2 = 0;
int j = 1;
//test
// for (int i = 1; i <= m; i++) work(i);
for (int i = 1; i <= q; i++)
{
while (j <= que[i].c) work(j), j++;
int a = que[i].a, b = que[i].b;
que[i].ans = f[col[a]][col[b]];
}
sort(que + 1, que + q + 1, [](Que A, Que B) {
return A.id < B.id;
});
for (int i = 1; i <= q; i++) cout << que[i].ans;
cout << "\n";
}
int main()
{
tt = read();
T = tt;
while (tt--) solve();
return 0;
}
/*
400
5 5 0
0405020501
0404050302
0105050105
0304010205
0402030205
*/
详细
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 15920kb
input:
2 5 2 4 0305040201 0404040404 030300 020500 050102 020501 6 2 4 030603010601 010203060504 030202 060402 050602 060401
output:
cnt1:5 1011 cnt1:6 0100
result:
wrong answer 1st lines differ - expected: '1011', found: 'cnt1:5'