1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| #include<bits/stdc++.h> const int N=1e3+10,mod=998244353,L=1e4+10; int n,m,ans,tot,top,min=INT_MAX,cir[N],w0[N],w1[N],deg[N],u[N],v[N],w[N],pre[N],suf[N],stk[N],hed[N],to[N<<1],val[N<<1],nxt[N<<1],fac[N*L],ifac[L]; bool vis[N],onc[N],inc[N]; void initgraph(){ tot=0; memset(hed,-1,sizeof(hed)); } void initfac(){ fac[0]=ifac[0]=ifac[1]=1; for(int i=1;i<N*L;i++)fac[i]=(long long)fac[i-1]*i%mod; for(int i=2;i<L;i++)ifac[i]=(long long)(mod-mod/i)*ifac[mod%i]%mod; for(int i=1;i<L;i++)ifac[i]=(long long)ifac[i-1]*ifac[i]%mod; } inline int C(int n,int m){return n<m?0:(long long)fac[n]*ifac[m]%mod*ifac[n-m]%mod;} inline void link(int u,int v,int w){nxt[tot]=hed[u],to[tot]=v,val[tot]=w,hed[u]=tot++;} inline int calc_fac(int x){ int res=1; for(int i=1;i<=x;i++)res=(long long)res*i%mod; return res; } void solve_tree(){ int ans=1; for(int u,v,w,i=1;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); if(w&1){puts("0"); return;} deg[u]+=w>>1,deg[v]+=w>>1; ans=(long long)ans*C(w,w>>1)%mod*(w>>1)%mod; } for(int i=1;i<=n;i++)ans=(long long)ans*fac[deg[i]-1]%mod; printf("%d\n",ans); } void dfs(int u,int fa){ stk[++top]=u,vis[u]=1; for(int i=hed[u];~i;i=nxt[i]) if(to[i]!=fa){ if(vis[to[i]]){ if(*cir)continue; cir[++*cir]=val[i]; for(int x=u;x!=to[i];x=to[pre[x]^1]){ cir[++*cir]=val[pre[x]]; } }else{ pre[to[i]]=i; dfs(to[i],u); } } --top; } void ordered_circle(){ int same=-1; if(u[cir[1]]==u[cir[2]])same=u[cir[1]]; if(u[cir[1]]==v[cir[2]])same=u[cir[1]]; if(v[cir[1]]==u[cir[2]])same=v[cir[1]]; if(v[cir[1]]==v[cir[2]])same=v[cir[1]]; assert(~same); int s=u[cir[1]]+v[cir[1]]-same; for(int i=1;i<=*cir;i++){ if(u[cir[i]]!=s)std::swap(u[cir[i]],v[cir[i]]); s=v[cir[i]]; } } int calc(int cur){ memset(deg,0,sizeof(deg)); int ans=1,sum=0,ano=1; for(int i=1;i<=m;i++){ if(inc[i]){ if((w[i]+cur)&1)return 0; w0[i]=(w[i]+cur)>>1; w1[i]=(w[i]-cur)>>1; }else{ w0[i]=w1[i]=w[i]>>1; } deg[u[i]]+=w1[i]; deg[v[i]]+=w0[i]; ans=(long long)ans*C(w[i],w0[i])%mod; } for(int i=1;i<=n;i++)ans=(long long)ans*fac[deg[i]-1]%mod; for(int i=1;i<=m;i++)if(!inc[i])ano=(long long)ano*w0[i]%mod; for(int k=1;k<=*cir;k++)pre[k]=(long long)pre[k-1]*w0[cir[k]]%mod; for(int k=*cir;k>=1;k--)suf[k]=(long long)suf[k+1]*w1[cir[k]]%mod; for(int k=1;k<=*cir;k++){ sum=(sum+(long long)pre[k-1]*suf[k+1]%mod*ano)%mod; } return (long long)sum*ans%mod; } int main(){ #ifdef Ciel freopen("1.in","r",stdin); #endif initfac(); initgraph(); scanf("%d%d",&n,&m); if(n==m+1)return solve_tree(),0; for(int i=1;i<=m;i++){ scanf("%d%d%d",&u[i],&v[i],&w[i]); link(u[i],v[i],i); link(v[i],u[i],i); deg[u[i]]+=w[i]; deg[v[i]]+=w[i]; } for(int i=1;i<=n;i++)if(deg[i]&1)return puts("0"),0; dfs(1,0); ordered_circle(); for(int i=1;i<=*cir;i++){ inc[cir[i]]=onc[u[cir[i]]]=onc[v[cir[i]]]=true; min=std::min(min,w[cir[i]]); } pre[0]=suf[0]=pre[*cir+1]=suf[*cir+1]=1; for(int d=-min;d<=min;d++)ans=(ans+calc(d))%mod; printf("%d\n",ans); }
|