2018.10.25 uoj#308. 【UNR #2】UOJ拯救計劃(排列組合)
阿新 • • 發佈:2018-12-17
傳送門 有一個顯然的式子: 這個東西貌似是個。 於是需要仔細觀察資料範圍。 咦模數等於? 那麼對於在的時候模都是了。 因此只用討論和的方案數。 什麼? 沒錯,題目上並沒有說過啊。 還有就是貌似邊數跟題目描述不太一樣。 程式碼:
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
const int N=1e5+5,M=2e6+5,mod=6;
int T,n,m,K,first[N],cnt=0,tot=0,fa[N],col[N],ans;
struct edge{int v,next;}e[M<< 1];
inline void addedge(int u,int v){e[++cnt].v=v,e[cnt].next=first[u],first[u]=cnt;}
inline void add(int u,int v){addedge(u,v),addedge(v,u);}
inline bool dfs(int p,int f){
col[p]=f;
for(int i=first[p];i;i=e[i].next){
int v=e[i].v;
if(~col[v]){if(!(col[v]^f))return false;}
else if(!dfs(v,f^1 ))return false;
}
return true;
}
inline int find(int x){return x==fa[x]?fa[x]:fa[x]=find(fa[x]);}
int main(){
T=read();
while(T--){
n=read(),m=read(),K=read();
if(!m){
ans=1;
for(int i=1;i<n;++i){
ans<<=1;
if(ans>=mod)ans-=mod;
}
--ans;
if(ans<0)ans+=mod;
ans=ans*K%mod*(K-1)%mod;
ans+=K%mod;
if(ans>=mod)ans-=mod;
}
else{
cnt=0,tot=0,ans=1;
for(int i=1;i<=n;++i)first[i]=0,fa[i]=i,col[i]=-1;
for(int i=1,u,v,fx,fy;i<=m;++i){
u=read(),v=read(),add(u,v),add(v,u),fx=find(u),fy=find(v);
if(fx!=fy)fa[fx]=fy;
}
for(int i=1,f;i<=n;++i)
if(~col[i])continue;
else{
if(!dfs(i,0)){ans=0;break;}
++tot;
}
if(ans){
for(int i=1;i<tot;++i){
ans<<=1;
if(ans>=mod)ans-=mod;
}
ans=ans*K%mod*(K-1)%mod;
}
}
printf("%d\n",ans);
}
return 0;
}