题目链接:http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=748&pid=1002

题解:

做题的时候只是想到用dfs暴搜,结果超时了。(刚学dfs时以为它无所不能,后来渐渐不太喜欢了,因为太暴力了,经常超时)

TLE wa代码如下:

#include<bits/stdc++.h>  

using namespace std;  

vector<int>v0[100005],v1[100005];
int vis[2][100005],ans; void dfs(int k, int flag, int step)//flag标记男女,0为男,1为女。
{
if(step==4) {ans++; return ;} if(flag)
{
int sum = v1[k].size();
for(int i = 0; i<sum; i++)
if(!vis[0][v1[k][i]])
{
vis[0][v1[k][i]] = 1;
dfs(v1[k][i],0,step+1);
vis[0][v1[k][i]] = 0;
}
} else
{
int sum = v0[k].size();
for(int i = 0; i<sum; i++)
if(!vis[1][v0[k][i]])
{
vis[1][v0[k][i]] = 1;
dfs(v0[k][i],1,step+1);
vis[1][v0[k][i]] = 0;
}
}
} int main()
{
int n,m,k,T,t0,t1;
scanf("%d",&T);
while(T--)
{
ans = 0;
scanf("%d%d%d",&n,&m,&k);
for(int i = 1; i<=n; i++) v0[i].clear();
for(int i = 1; i<=m; i++) v1[i].clear();
memset(vis,0,sizeof(vis));
for(int i = 0; i<k; i++)
{
scanf("%d%d",&t0,&t1);
v0[t0].push_back(t1);
v1[t1].push_back(t0);
} for(int i = 1; i<=n; i++)
{vis[0][i] = 1; dfs(i,0,1); vis[0][i] = 0;}
for(int i = 1; i<=m; i++)
{vis[1][i] = 1; dfs(i,1,1); vis[1][i] = 0;} printf("%d\n",ans);
}
return 0;
}

后来大致看了题解,就觉得可以逐个点枚举,从第一个到第四个,用for循环,但仔细想想,这跟dfs没用本质的区别,只不过递推与递归的实现不同。

于是又认真看了题解。发现他不是从第一个点开始枚举的,而是从第二第三个点枚举的,为什么呢?其实画一下图就可以很好理解。四个点构成三条边,如果从第一个点开始枚举,那么所有人都必须知道朋友是谁,才能继续枚举下去,用图的话来说,是只有知道下一个点是谁,才能构成线段,所以只能一个一个枚举。但是如果从第二第三个开始枚举,即从中间的那条边开始,即枚举中间那条边,那么只需要一个性别知道朋友是谁和个数,另一个性别知道朋友的个数,则直接可以分别用(个数-1),即减去当前已确定的对方,就是剩下的对方,然后相乘。

上述解释可能很模糊,但可以抽象成一种思维方法。就好像第二个点和第三个点处在中间,其两边都还连有点,那么这两个点的地位相对第一第四个点来说要刚,因为其起到的作用,或影响范围更广。所以就挑选影响范围广的进行操作,那么气效率也更高。

学习之处:大致来讲,挑选影响范围广的进行操作,那么其效率会更高。

代码如下:

#include<bits/stdc++.h>  

using namespace std;  

vector<int>v[100005];//v记录男生的朋友
int cnt[100005];//cnt记录女生的朋友个数
int main()
{
int T, n,m,k,x,y;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&k);
memset(cnt,0,sizeof(cnt));
for(int i = 1; i<=n; i++)
v[i].clear(); for(int i = 0; i<k; i++)
{
scanf("%d%d",&x,&y);
v[x].push_back(y);
cnt[y]++;
} long long ans = 0;//用int会溢出 for(int i = 1; i<=n; i++)//枚举男生,即第三个点
{
int sum = v[i].size();//这个男生的朋友个数
for(int j = 0; j<sum; j++)//枚举与之为朋友的女生,即第二个点
{
/*这条公式非常精彩。其实第一第二个循环实际是枚举中间那条边。
首先中间的边已经确定,那么只需要知道第二第三个点的朋友个数,
然后再减去对方,就是剩下的朋友数,再相乘,就是在中间的边已确立
的情况下,不同连线方式的个数。*/
ans += (cnt[v[i][j]]-1) * (sum-1);
}
} printf("%lld\n",ans*2);
}
return 0;
}

BestCoder Round #92 1002 Count the Sheep —— 枚举+技巧的更多相关文章

  1. HDU_6016_(Bestcoder round #92 1002)_(dfs)(暴力)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6016 题意:给定男羊和女羊的朋友关系,即给定一个图,问从任意一只羊开始连续数四只不相同的羊的方法数. ...

  2. Manacher BestCoder Round #49 ($) 1002 Three Palindromes

    题目传送门 /* Manacher:该算法能求最长回文串,思路时依据回文半径p数组找到第一个和第三个会文串,然后暴力枚举判断是否存在中间的回文串 另外,在原字符串没啥用时可以直接覆盖,省去一个数组空间 ...

  3. 暴力+降复杂度 BestCoder Round #39 1002 Mutiple

    题目传送门 /* 设一个b[]来保存每一个a[]的质因数的id,从后往前每一次更新质因数的id, 若没有,默认加0,nlogn复杂度: 我用暴力竟然水过去了:) */ #include <cst ...

  4. 矩阵快速幂---BestCoder Round#8 1002

    当要求递推数列的第n项且n很大时,怎么快速求得第n项呢?可以用矩阵快速幂来加速计算.我们可以用矩阵来表示数列递推公式比如fibonacci数列 可以表示为 [f(n)   f(n-1)] = [f(n ...

  5. 贪心/二分查找 BestCoder Round #43 1002 pog loves szh II

    题目传送门 /* 贪心/二分查找:首先对ai%=p,然后sort,这样的话就有序能使用二分查找.贪心的思想是每次找到一个aj使得和为p-1(如果有的话) 当然有可能两个数和超过p,那么an的值最优,每 ...

  6. 二分图判定+点染色/并查集 BestCoder Round #48 ($) 1002 wyh2000 and pupil

    题目传送门 /* 二分图判定+点染色:因为有很多联通块,要对所有点二分图匹配,若不能,存在点是无法分配的,no 每一次二分图匹配时,将点多的集合加大最后第一个集合去 注意:n <= 1,no,两 ...

  7. hdu 5195 DZY Loves Topological Sorting BestCoder Round #35 1002 [ 拓扑排序 + 优先队列 || 线段树 ]

    传送门 DZY Loves Topological Sorting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131 ...

  8. BestCoder Round #92 比赛记录

    上午考完试后看到了晚上的BestCoder比赛,全机房都来参加 感觉压力好大啊QAQ,要被虐了. 7:00 比赛开始了,迅速点进了T1 大呼这好水啊!告诉了同桌怎么看中文题面 然后就开始码码码,4分1 ...

  9. BestCoder Round #56 1002 Clarke and problem 1003 Clarke and puzzle (dp,二维bit或线段树)

    今天第二次做BC,不习惯hdu的oj,CE过2次... 1002 Clarke and problem 和Codeforces Round #319 (Div. 2) B Modulo Sum思路差不 ...

随机推荐

  1. 反向代理服务器(Reverse Proxy)

    反向代理服务器(Reverse Proxy)   普通代理服务器是帮助内部网络的计算机访问外部网络.通常,代理服务器同时连接内网和外网.首先内网的计算机需要设置代理服务器地址和端口,然后将HTTP请求 ...

  2. javascript好文 --- 深入理解可视区尺寸client

    可视区大小 可视区大小client又称为可见大小或客户区大小,指的是元素内容及其内边距所占据的空间大小 clientHeight clientHeight属性返回元素节点的可见高度 clientHei ...

  3. Java使用QRCode.jar生成与解析二维码

    原文V:http://www.cnblogs.com/bigroc/p/7496995.html#3797682 正题:Java使用QRCode.jar生成与解析二维码demo 欢迎新手共勉,大神监督 ...

  4. Android自定义控件之基本原理(一)

    前言: 在日常的Android开发中会经常和控件打交道,有时Android提供的控件未必能满足业务的需求,这个时候就需要我们实现自定义一些控件,今天先大致了解一下自定义控件的要求和实现的基本原理. 自 ...

  5. 使用sqlalchemy查询并删除数据表的唯一性索引

    简单描述表结构,字段类型 desc tabl_name 删除索引:alter table `db`.`table_name` drop index `index_name`  注意里面的特殊符号: ` ...

  6. HDU 4635 Strongly connected(强连通)经典

    Strongly connected Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  7. pascals-triangleI、II——生成规律的三角形

    1.Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5,Ret ...

  8. Codeforces初体验

    Codeforces印象 这两天抽时间去codeforces体验了一把. 首先,果然有众多大牛存在.非常多名人一直參加每周一次的比赛.积分2000+,并參与出题. 另外.上面题目非常多.预计至少一千题 ...

  9. GB28181对接视频流

    今天抽空写下以GB28181的方式获取摄像机视频流以备后用,同时也希望能帮助到正着手开发GB28181对接视频的同学,这块的资料实在不多. 今天讲的内容不涉及到平台对接,平台对接下次有时间再讲,平台对 ...

  10. Selenium系列之--07 操作远程浏览器

    Selenium远程控制浏览,可以通过如下两种方式实现,本质上都是Selenium Grid a.  客户机启Selenium Standalone Server 作为远程服务,服务端通过调用Remo ...