当前位置: 代码迷 >> 综合 >> 2020-09-3 CCF CSP 点亮数字人生(拓扑排序 判环)
  详细解决方案

2020-09-3 CCF CSP 点亮数字人生(拓扑排序 判环)

热度:47   发布时间:2024-02-24 14:45:47.0

经典急了急了。。

第三题判断环的存在有一万种方式,拓扑排序,甚至撸上去一个tarjan都行,非自己图快意淫出一个不存在的递归算法然后把心态调崩了。。导致只拿了五十分。

100分:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
vector<int> iput[N], oput[N];
string op[N];
int du[N],bdu[N];
int h[N], tot, n, m;
struct {int to,nxt;} e[N << 4];
int w[N];
void init()
{memset(h, -1, sizeof h); tot = 0;for(int i = 0; i < N; ++i) iput[i].clear(), oput[i].clear();memset(du, 0, sizeof du);
}
void add(int a,int b)
{e[tot].to = b, e[tot].nxt = h[a], h[a] = tot ++;
}
bool topsort()
{for(int i = 1; i <= n + m; ++i) bdu[i] = du[i];queue<int> q;for(int i = 1; i <= n + m; ++i) if(!bdu[i]) q.push(i);while(q.size()){int u = q.front(); q.pop();for(int i = h[u]; ~i; i = e[i].nxt){int to = e[i].to;if(op[to] == "AND" || op[to] == "NAND") w[to] &= w[u];else if(op[to] == "OR" || op[to] == "NOR") w[to] |= w[u];else if(op[to] == "XOR") w[to] ^= w[u];else if(op[to] == "NOT") w[to] = !w[u];if(--bdu[to] == 0) {if(op[to] == "NOR" || op[to] == "NAND") w[to] = !w[to];q.push(to);}}}for(int i = n + 1; i <= n + m; ++i) if(bdu[i]) return false;return true;
}
int main()
{//freopen("1.txt", "r", stdin);int T; cin >> T;while(T --){init();scanf("%d%d", &n, &m);for(int i = 1; i <= m; ++i){int id = i + n, cnt; cin >> op[id] >> cnt;for(int j = 0; j < cnt; ++j){string s; cin >> s;int num = 0;for(int k = 1; k < s.size(); ++k) num = num * 10 + s[k] - '0';if(s[0] == 'O') num += n;add(num, id);  du[id] ++;}}int k; scanf("%d", &k);for(int i = 0; i < k; ++i){for(int j = 1; j <= n; ++j){int x; scanf("%d", &x);iput[i].push_back(x);}}for(int i = 0; i < k; ++i){int cnt; cin >> cnt;for(int j = 0; j < cnt; ++j){int x; scanf("%d", &x);oput[i].push_back(x + n); }}if(!topsort()) puts("LOOP");else for(int i = 0; i < k; ++i){memset(w, 0, sizeof w);for(int j = 1; j <= n; ++j) w[j] = iput[i][j - 1];for(int j = n + 1; j <= n + m; ++j)if(op[j] == "AND" || op[j] == "NAND") w[j] = 1;topsort();for(int j = 0; j < oput[i].size(); ++j){int t = oput[i][j];	printf("%d ", w[t]);}				puts("");	}		}}