如题,思路大概先建图,然后跑一边染色,判是否在端点含有 U 或者奇环(dfs1 返回 true)
然后把此结点所在连通块全部遍历,赋值为 U 或者非 U。所以这种方法错在哪呢?
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int N=1e5+5;
struct NODE{int stat,r;}a[N];
int C,T,n,m,ans,vzf[N];
bool vis[N],col[N];
vector<int>g[N],e[N],gn[N];
bool dfs1(int x,int val){
if(vis[x])return false;
if(a[x].stat==0||a[x].stat==1||a[x].stat==2)return false;
if(a[x].stat==3)return true;
if(vzf[x]==-val)return true;
if(vzf[x]==val)return false;
vzf[x]=val;
return dfs1(a[x].r,val*(a[x].stat==4?1:-1));
}
void dfs2(int x,bool can){
if(vis[x])return;
vis[x]=true;
if(can)col[x]=true;
for(int v:gn[x])dfs2(v,can);
}
int main(){
scanf("%d%d",&C,&T);
while(T--){
scanf("%d%d",&n,&m);
while(m--){
char op;
int x,y;
scanf(" %c%d",&op,&x);
if(op=='T')a[x].stat=1;
else if(op=='F')a[x].stat=2;
else if(op=='U')a[x].stat=3;
else if(op=='+'){
scanf("%d",&y);
if(a[y].stat==1||a[y].stat==2||a[y].stat==3)a[x].stat=a[y].stat;
else a[x].stat=4,a[x].r=y;
}
else{
scanf("%d",&y);
if(a[y].stat==1)a[x].stat=2;
else if(a[y].stat==2)a[x].stat=1;
else if(a[y].stat==3)a[x].stat=3;
else a[x].stat=5,a[x].r=y;
}
}
for(int i=1;i<=n;i++){
if(a[i].stat==4){
g[i].push_back(a[i].r);
e[i].push_back(1);
gn[i].push_back(a[i].r);
gn[a[i].r].push_back(i);
}
else if(a[i].stat==5){
g[i].push_back(a[i].r);
e[i].push_back(-1);
gn[i].push_back(a[i].r);
gn[a[i].r].push_back(i);
}
}
for(int i=1;i<=n;i++)dfs2(i,dfs1(i,1));
for(int i=1;i<=n;i++)ans+=col[i];
printf("%d\n",ans);
ans=0;
memset(vis,false,sizeof(vis));
memset(col,false,sizeof(col));
memset(vzf,0,sizeof(vzf));
for(int i=1;i<=n;i++)g[i].clear(),e[i].clear(),gn[i].clear(),a[i].stat=0,a[i].r=0;
}
return 0;
}