题解
相关
感觉都讲得挺清楚的了。
代码挺矬的。。。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
using namespace std;
const int N=55,M=205,mod=1000000007;
int n,m,k,u,v,cnt,tot,idx,ans,head[N],id[M],to[M],nxt[M],dfn[N],low[N],in[N],stk[M];
bool ck[M];
set<int> st;
void adde(int u,int v){
to[++cnt]=v;
nxt[cnt]=head[u];
head[u]=cnt;
}
int fastpow(int a,int x){
int res=1;
while(x){
if(x&1){
res=1LL*res*a%mod;
}
x>>=1;
a=1LL*a*a%mod;
}
return res;
}
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int C(int n,int m){
int res=1;
for(int i=1;i<=m;i++){
res=1LL*res*(n-i+1)%mod*fastpow(i,mod-2)%mod;
}
return res;
}
void tarjan(int pre,int u){
dfn[u]=low[u]=++idx;
for(int v=head[u];v;v=nxt[v]){
if(to[v]!=pre&&!ck[id[v]]){
ck[id[v]]=true;
stk[++stk[0]]=v;
}
if(!dfn[to[v]]){
tarjan(u,to[v]);
low[u]=min(low[u],low[to[v]]);
if(low[to[v]]>=dfn[u]){
tot++;
int siz=0;
st.clear();
memset(in,0,sizeof(in));
do{
st.insert(to[stk[stk[0]]]);
st.insert(to[stk[stk[0]]^1]);
in[to[stk[stk[0]]]]++;
in[to[stk[stk[0]]^1]]++;
siz++;
}while(id[v]!=id[stk[stk[0]--]]);
bool flag=true;
for(set<int>::iterator it=st.begin();it!=st.end();it++){
if(in[*it]!=2){
flag=false;
break;
}
}
if(flag==true||siz==1){
int tmp=0;
for(int i=0;i<siz;i++){
tmp=(tmp+fastpow(k,gcd(i,siz)))%mod;
}
ans=(1LL*ans*tmp%mod*fastpow(siz,mod-2)%mod)%mod;
}else{
ans=1LL*ans*C(siz+k-1,k-1)%mod;
}
}
}else{
low[u]=min(low[u],dfn[to[v]]);
}
}
}
int main(){
scanf("%d%d%d",&n,&m,&k);
ans=cnt=1;
for(int i=1;i<=m;i++){
scanf("%d%d",&u,&v);
adde(u,v);
id[cnt]=i;
adde(v,u);
id[cnt]=i;
}
for(int i=1;i<=n;i++){
if(!dfn[i]){
tarjan(0,i);
}
}
printf("%d\n",ans);
return 0;
}