拓扑排序,一次通过拓扑排序判断环,再一次通过拓扑排序求解,复杂度O(Tkm), T为测试样例数,时间很紧,几乎贴着过的
#include<bits/stdc++.h>
using namespace std;
const int N = 3007, M = 1e5+7;
struct edge{
int f,t,n;
}g[M];
struct que{
vector<int> v,v2;
}q[10007];
int head[N];
int m,n,k,qq,cnt=1;
void add(int f,int t){
g[cnt].n = head[f];
g[cnt].t = t;
g[cnt].f= f;
head[f]=cnt++;
}
vector<int> in[N];
string ss[N];
int d[N], ans[N], h[N];
void init(){
memset(head,0,sizeof head);
memset(d,0,sizeof d);
memset(h,-1,sizeof h);
cnt=1;
for(int i=1;i<=n;i++) in[i].clear();
}
int toint(string s){
int x=0;
for(int i=1;i<s.size();i++) x = x*10+s[i]-'0';
return x;
}
int find(int x){
if(h[x]<0) return x;
else return h[x]=find(h[x]);
}
void sunion(int x,int y){
int fx = find(x), fy = find(y);
if(fx!=fy){
h[fx] = fy;
}
}
int dd[N];
int dfs(){
for(int i=1+m;i<=m+n;i++) dd[i]=d[i];
queue<int> q2;
int idx = 0;
for(int i=1;i<=m;i++){
q2.push(i);
}
while(!q2.empty()){
int u = q2.front();
q2.pop();
for(int i=head[u];i;i=g[i].n){
int to = g[i].t;
dd[to]--;
if(!dd[to]) q2.push(to), idx++;
}
}
//cout<<idx<<'\n';
return idx!=n;
}
int val[N];
int dod(int x){
string sss = ss[x];
if(sss=="NOT"){
return (in[x][0]^1);
}
else if(sss=="AND"){
int res = 1;
for(int i=0;i<in[x].size();i++){
res = (res&in[x][i]);
}
return res;
}
else if(sss=="NAND"){
int res = 1;
for(int i=0;i<in[x].size();i++){
res = (res&in[x][i]);
}
return (res^1);
}
else if(sss=="OR"){
int res = 0;
for(int i=0;i<in[x].size();i++){
res = (res|in[x][i]);
}
return res;
}
else if(sss=="XOR"){
int res = 0;
for(int i=0;i<in[x].size();i++){
res = (res^in[x][i]);
}
return res;
}
else{
int res = 0;
for(int i=0;i<in[x].size();i++){
res = (res|in[x][i]);
}
return (res^1);
}
}
void tops(int x){
queue<int> q2;
for(int i=1;i<=m;i++) ans[i] = q[x].v[i-1], q2.push(i);
for(int i=1+m;i<=n+m;i++) in[i].clear();
while(!q2.empty()){
int u = q2.front();
q2.pop();
for(int i=head[u];i;i=g[i].n){
int to = g[i].t;
in[to].push_back(ans[u]);
if(in[to].size()==d[to]){
ans[to] = dod(to);
q2.push(to);
}
}
}
//cout<<ans[3+m]<<'\n';
}
void solve(){
init();
cin>>m>>n;
string s;
for(int i=1;i<=n;i++){
cin>>ss[i+m]>>k;
d[i+m]=k;
for(int j=0;j<k;j++){
cin>>s;
int x = toint(s);
if(s[0]=='I') add(x,i+m);
else add(x+m,i+m);
}
}
cin>>qq;
for(int i=0;i<qq;i++){
q[i].v.resize(m);
for(int j=0;j<m;j++) cin>>q[i].v[j];
}
for(int i=0;i<qq;i++){
cin>>k;
q[i].v2.resize(k);
for(int j=0;j<k;j++) cin>>q[i].v2[j];
}
if(dfs()){
cout<<"LOOP"<<'\n';
}
else{
for(int i=0;i<qq;i++){
tops(i);
for(int j=0;j<q[i].v2.size();j++){
//cout<<'!'<<q[i].v2[j]+m<<'\n';
cout<<ans[q[i].v2[j]+m];
if(j!=q[i].v2.size()-1) cout<<' ';
else cout<<'\n';
}
}
}
}
int main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--) solve();
}
/*
1
3 5
XOR 2 I1 I2
XOR 2 O1 I3
AND 2 O1 I3
AND 2 I1 I2
OR 2 O3 O4
1
0 1 1
2 5 2
*/
求解:你好,n为啥要开到3000呀?510不就够用吗?
太难了