有生以来做过的bzoj比A+B还简单的最水的题。(确信)
不解释。
UPD:据说这题正解应当是矩阵树定理?但是这个不是用来最小生成树计数的么?有生之年会补的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #define dbg(x) cerr << #x << " = " << x <<endl 8 using namespace std; 9 typedef long long ll; 10 typedef double db; 11 typedef pair<int,int> pii; 12 template<typename T>inline T _min(T A,T B){return A<B?A:B;} 13 template<typename T>inline T _max(T A,T B){return A>B?A:B;} 14 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;} 15 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;} 16 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;} 17 template<typename T>inline T read(T&x){ 18 x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1; 19 while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x; 20 } 21 const int N=60,P=1e9+7; 22 char s[N]; 23 int n; 24 struct thxorz{int to,nxt,w;}G[10000]; 25 int Head[N],tot; 26 inline void Addedge(int x,int y,int z){G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot,G[tot].w=z;} 27 #define y G[j].to 28 int dis[N],cnt[N]; 29 priority_queue<pii,vector<pii>,greater<pii> > q; 30 inline void stothxorz(){ 31 memset(dis,0x3f,sizeof dis);q.push(make_pair(dis[1]=0,1));cnt[1]=1; 32 while(!q.empty()){ 33 int x=q.top().second,d=q.top().first;q.pop(); 34 if(dis[x]^d)continue; 35 for(register int j=Head[x];j;j=G[j].nxt) 36 if(dis[y]==d+G[j].w)++cnt[y]; 37 else if(MIN(dis[y],d+G[j].w))cnt[y]=1,q.push(make_pair(dis[y],y)); 38 } 39 } 40 #undef y 41 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout); 42 read(n); 43 for(register int i=1;i<=n;++i){ 44 scanf("%s",s+1); 45 for(register int j=1;j<=n;++j)if(s[j]-'0')Addedge(i,j,s[j]-'0'); 46 } 47 stothxorz(); 48 int res=1; 49 for(register int i=1;i<=n;++i)res=res*1ll*cnt[i]%P; 50 printf("%d ",res); 51 return 0; 52 }