NC17667. Enumeration not optimization
描述
输入描述
The first line contains two integers n, m, which are the number of vertices and the number of edges.
In the following m lines, each line contains three integers x, y, z, which means there is an edge between x and y, whose weight is z.
1 <= n <= 12
1 <= m <= 1000
1 <= x <= n
1 <= y <= n
1 <= z <= 5000
输出描述
You should ouput one line, which contains the answer.
示例1
输入:
4 5 1 2 1 1 3 3 1 4 1 2 3 4 3 4 1
输出:
303
示例2
输入:
4 5 1 2 1 1 3 3 1 4 1 2 3 4 3 4 2
输出:
336
C++ 解法, 执行用时: 154ms, 内存消耗: 1272K, 提交时间: 2022-05-01 14:00:03
#include<bits/stdc++.h> using namespace std; const int mod=1000000007; long long f[13][1<<13],g[13][1<<13]; long long h[1<<13],x[3000],y[3000],n,m,c[13][13],w[3000],ans=0; int main() { scanf("%lld%lld",&n,&m); for(int i=1;i<=m;++i) { scanf("%lld%lld%lld",&x[i],&y[i],&w[i]); --x[i]; --y[i]; ++c[x[i]][y[i]]; ++c[y[i]][x[i]]; } for(int i=1;i<1<<n;++i) { for(int j=i;j;j>>=1) h[i]+=j&1; for(int j=0;j<n;++j) if(i>>j&1) { int u=i^(1<<j),v=u&(-u); if(!u) { f[j][i]=g[j][i]=1; break; } for(int k=u;k;k=(k-1)&u) if(k&v) { for(int l=0;l<n;++l) if((k>>l)&1) { int subsum=(f[l][k]+h[k]*g[l][k])%mod*g[j][i^k]%mod; f[j][i]=(f[j][i]+(f[j][i^k]*g[l][k]%mod+subsum)%mod*c[j][l])%mod; g[j][i]=(g[j][i]+g[j][i^k]*g[l][k]%mod*c[j][l]%mod)%mod; } } } } int s=(1<<n)-1; for(int i=1;i<=m;++i) for(int j=1<<x[i];j<1<<n;j=(j+1)|(1<<x[i])) ans=(ans+w[i]*(f[x[i]][j]*g[y[i]][s^j]%mod+f[y[i]][s^j]*g[x[i]][j]%mod))%mod; printf("%lld\n",ans); return 0; }