您的位置:首页 > 其它

【HDU 5305】Friends 多校第二场(双向DFS)

2017-05-09 15:19 337 查看

依据题意的话最多32条边,直接暴力的话 2 ^ 32肯定超时了。我们能够分两次搜索时间复杂度降低为 2 * 2  ^ 16

唯一须要注意的就是对眼下状态的哈希处理。

我採用的是 十进制表示法

跑的还是比較快的,可能是用STL函数的原因添加了一些常数复杂度。

#include<map>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,int> pill;
const int maxn = 55;
struct Edge{
int a,b;
}edge[maxn];
int n,m;
LL cnt,base[15];
int _count[15];
map<pill,int>vis;
void init(){
base[1] = 1;
for(int i = 2; i < 10; i++)
base[i] = base[i - 1] * 10;
}
void calc(int state1,int state2,int &a,int &b){
int base = 1;
for(int i = 1; i <= n; i++){
int d1 = state1 % 10, d2 = state2 % 10;
int v1 = _count[i] - d1, v2 = _count[i] - d2;
a += base * v1;
b += base * v2;
base *= 10;
state1 /= 10;
state2 /= 10;
}
}
void dfs1(int now,int finish,int state1,int state2){
if(now == finish){
vis[make_pair(state1,state2)] ++;
return;
}
int a = edge[now].a, b = edge[now].b;
dfs1(now + 1,finish,state1 + base[a] + base[b],state2);
dfs1(now + 1,finish,state1,state2 + base[a] + base[b]);
}
void dfs2(int now,int finish,int state1,int state2){
if(now == finish){
int x = 0,y = 0;
calc(state1,state2,x,y);
if(x >= 0 && y >= 0)
cnt += vis[make_pair(x,y)];
return;
}
int a = edge[now].a, b = edge[now].b;
dfs2(now + 1,finish,state1 + base[a] + base[b],state2);
dfs2(now + 1,finish,state1,state2 + base[a] + base[b]);
}
int main(){
int T;
init();
scanf("%d",&T);
while(T--){
vis.clear();
memset(_count,0,sizeof(_count));
scanf("%d%d",&n,&m);
for(int i = 0; i < m; i++){
scanf("%d%d",&edge[i].a,&edge[i].b);
_count[edge[i].a] ++;
_count[edge[i].b] ++;
}
int ok = 1;
for(int i = 1; i <= n; i++){
if(_count[i] % 2 != 0){
ok = 0;
break;
}
_count[i] /= 2;
}
cnt = 0;
if(ok){
dfs1(0,m / 2,0,0);
dfs2(m / 2,m,0,0);
}
printf("%d\n",cnt);
}
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: