给定一张n个点的无向图,统计有多少条简单路径恰好经过了4个点。
背景
在美丽的比特镇一共有n个景区,编号依次为1到n,它们之间通过若干条双向道路连接。
Byteasar慕名来到了比特镇旅游,不过由于昂贵的门票费,他只能负担起4个景区的门票费。他可以在任意景区开始游览,然后结束在任意景区。
Byteasar的旅游习惯比较特殊,一旦他路过了一个景区,他就一定会进去参观,并且他永远不会参观同一个景区两次。所以他想知道,有多少种可行的旅游路线,使得他可以恰好参观4个景区呢?即,有多少条简单路径恰好经过了4个点。
Input
第一行包含两个整数n,表示景区的总数。
第2至第n+ 1行,每行一个长度为n的01字符串,第i+ 1行第j 个字符为0表示i 和j 之间没有道路,为1表示有一条道路。
输入数据保证(i;j)的连接情况等于(j; i)的连接情况,且(i;i)恒为0。
Output
输出一行一个整数,即可行的路线总数。
Example
tour.in | tour.out |
---|---|
4 | 8 |
0101 | |
1010 | |
0101 | |
1010 |
8条路线分别为:
1->2->3->4, 4->3->2->1,
2->3->4->1, 1->4->3->2,
3->4->1->2, 2->1->4->3,
4->1->2->3, 3->2->1->4。
Notes
测试点编号 n |
---|
1 = 5 |
2 = 10 |
3 = 20 |
4 = 50 |
5 = 300 |
6 = 300 |
7 = 300 |
8 = 1500 |
9 = 1500 |
10 = 1500 |
部分分做法
- 40分做法:暴力枚举,时间复杂度O(n^4)
- 70分做法:设经过的点为a-b-c-d,枚举中间边b-c,再枚举与b,c相连的点,设deg x 表示点x的度数,那么边b-c对答案的贡献为(deg b-1)(deg c- 1) - 经过b-c这条边的三元环个数。 计算三元环的个数只需要枚举除b,c之外的另一个点即可,时间复杂度O(n^3)
AC做法
70分算法的瓶颈在于三元环计数。
设S x 表示所有和x有边的点的集合,那么其实就是统计Sb与Sc的并集的元素数。将S用二进制压位存储即可并行计算。时间复杂度O(n^3/32)。
70分代码
统计Sb与Sc的并集的元素数未加优化,超时
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define LL long long
using namespace std;
const int maxn=