对于noip T2,给定 n,m,已知所有操作在5种操作中随机,每种操作里 i,j 在 [1,n] 中随机。我的代码在 i=j 的时候会连自环(见下),在"- i i"的时候(如果影响到最初的 xi 取值且原本的 xi 不需要为U)可能会出问题,求我代码出问题的概率。
如n=1,m=2,概率为 0.2(在"T/F 1 - 1 1","- 1 1 T/F 1","- 1 1 - 1 1"的时候会出问题,总共有 25 种情况)
代码:
#include<bits/stdc++.h>
using namespace std;
int t,n,m,ls[100010],xx,yy;
int ass[300010],tot,ans,temp[300010];
bool vis[300010],md[300010],vis2[300010];
char op[2];
struct edg{
int v,w;
};
vector<edg>g[300010];
map<pair<int,int>,int>mp;
void dfs(int u){
vis[u]=1;
for(int i=0;i<g[u].size();i++){
int v=g[u][i].v,w=g[u][i].w;
if(ass[u]!=0x3f3f3f3f) ass[v]=ass[u]*w;
if(!vis[v]){
temp[v]=temp[u]*w;
dfs(v);
}
else if(temp[v]*temp[u]!=w){
md[u]=1;
}
}
}
void dfs2(int u){
vis2[u]=1;
ass[u]=0;
//printf("%d\n",u);
for(int i=0;i<g[u].size();i++){
int v=g[u][i].v;
if(!vis2[v]) dfs2(v);
}
}
int main(){
scanf("%d",&t);
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
ans=0;
memset(ls,0,sizeof(ls));
memset(vis,0,sizeof(vis));
memset(ass,0x3f3f3f3f,sizeof(ass));
memset(temp,0,sizeof(temp));
memset(vis2,0,sizeof(vis2));
memset(md,0,sizeof(md));
ass[1]=-1;
ass[2]=0;
ass[3]=1;
tot=3;
mp.clear();
for(int i=1;i<=n;i++) mp[make_pair(i,0)]=++tot;
for(int i=1;i<=m;i++){
scanf("%s%d",op,&xx);
//cout<<op<<endl;
++ls[xx];
mp[make_pair(xx,ls[xx])]=++tot;
if(op[0]=='+'||op[0]=='-'){
scanf("%d",&yy);
if(xx==yy){
g[tot].push_back((edg){mp[make_pair(yy,ls[yy]-1)],(op[0]=='+'?1:-1)});
g[mp[make_pair(yy,ls[yy]-1)]].push_back((edg){tot,(op[0]=='+'?1:-1)});
}
//cout<<114514<<endl;
int temppp=mp[make_pair(yy,ls[yy])];
g[tot].push_back((edg){temppp,(op[0]=='+'?1:-1)});
g[temppp].push_back((edg){tot,(op[0]=='+'?1:-1)});
//printf("%d %d %d\n",tot,mp[make_pair(yy,ls[yy])],(op[0]=='+'?1:-1));
}
else if(op[0]=='T') g[tot].push_back((edg){3,1}),g[3].push_back((edg){tot,1});//,printf("%d %d 1\n",tot,3);
else if(op[0]=='U') g[tot].push_back((edg){2,1}),g[2].push_back((edg){tot,1});//,printf("%d %d 1\n",tot,2);
else g[tot].push_back((edg){1,1}),g[1].push_back((edg){tot,1});//,printf("%d %d 1\n",tot,1);
}
for(int i=1;i<=n;i++){
if(ls[i]!=0){
g[mp[make_pair(i,0)]].push_back((edg){mp[make_pair(i,ls[i])],1});
g[mp[make_pair(i,ls[i])]].push_back((edg){mp[make_pair(i,0)],1});
}
}
for(int i=1;i<=tot;i++){
if(!vis[i]) temp[i]=1,dfs(i);
}
for(int i=4;i<=tot;i++){
if(ass[i]!=0&&md[i]&&(!vis2[i])) dfs2(i);
}
for(int i=4;i<=n+3;i++) if(ass[i]==0) ++ans;
printf("%d\n",ans);
for(int i=1;i<=tot;i++) g[i].clear();
}
return 0;
}