题目大意
给一个N个点的无向图,求经过四个点的简单路径有多少条,正反都算。
70%N<=300
100%N<=1500
分析
70分做法:
我们考虑枚举中间的两个点i,j,那么只要统计他们伸出去的点有多少个就行了,设与i相连的点有fi个,与j相连的有fj个。方案数就是(fi-1)*(fj-1)-cnt,cnt就是i,j都能到达的点的个数,即长度为3的环的个数。
这样是N^3的。
100:
找cnt的时候压位就行了····
代码
#include<cstdio>
#include<algorithm>
using namespace std;
#define fo(i,j,k) for(i=j;i<=k;i++)
const int P=2097152,N=1505;
int pd[P],a[N][80],i,j,n,m,k,l,tmp,dur,c[N],b[N][N];
long long ans;
int main()
{
freopen("tour.in","r",stdin);
//freopen("tour.out","w",stdout);
scanf("%d\n",&n);
fo(i,0,(1<<21)-1)
fo(j,0,20) if (i&(1<<j)) pd[i]++;
fo(i,1,n)
{
tmp=0;
dur=1;
fo(j,1,n)
{
b[i][j]=getchar()-'0';
c[i]+=b[i][j];
a[i][dur]=a[i][dur]*2+b[i][j];
tmp++;
if (tmp==21)
{
tmp=0;
dur++;
}
}
scanf("\n");
}
fo(i,1,n)
fo(j,i+1,n) if (b[i][j])
{
ans=ans+(c[i]-1)*(c[j]-1);
tmp=0;
fo(k,1,dur)
tmp+=pd[a[i][k]&a[j][k]];
ans-=tmp;
}
printf("%lld",ans*2);
}
附bitset用法
#include<bitset>
bitset<maxn> f[maxn];
f[i][j]=1
ans+=(tot[i]-1) * (tot[j]-1);
ans-=(f[i] & f[j]).count();