HDU 6016 Count the Sheep BestCoder Round #93 1002 边贡献统计

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6016

题意:给你一个二分图,计算长度为4的所有通路数(点各异)。

题解:这题一眼能想到的是枚举顶点作为端点,dfs搜索四层做统计,但是跑极限数据很容易出现O(n²)的复杂度。如果做树形dp处理的话,由于本人太弱不会处理圈,至于也想到统计边贡献,但是还是不知道怎么处理。赛后hack的时候,看了一眼别人的代码,发现智商又被压制了。
对于长度为4的通路,我们设为A-B-C-D,当一条边有贡献的时候,必然是处于A-B、B-C或者C-D(A-B、C-D一样)。这时显然能发现,如果把边作为A-B(或者C-D),又要进行dfs,也就是说复杂度分分钟都能上天了。如果把边看作B-C的话,只要与B相连的边数和与C相连的边数相乘即可。而且如果这样处理的话,会发现其实与B或者C 相连的边会默认成A-B或者C-D。综上所述,计算边的贡献的时候,只要把边看作B-C统计即可。

代码如下:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
const int N=100005;

int T;
int n,m,k;
ll ans;
int x[N],y[N],c[N*2];

int main()
{
	cin>>T;
	while(T--)
	{
		cin>>n>>m>>k;
		memset(c,0,sizeof(c));
		for(int i = 0 ;i < k; i++)
		{
			scanf("%d%d",x+i,y+i);
			c[x[i]]++;
			c[y[i]+n]++;
		}
		ans = 0;
		for(int i = 0 ; i < k; i++)
			ans += 2LL * (c[x[i]] - 1) * (c[y[i]+n] - 1);//减一是消掉自身的,乘2是因为每条通路方向有两个
		printf("%I64d\n",ans);
	}
    return 0;
}

posted on 2017-02-26 12:41  57老帅了  阅读(185)  评论(0编辑  收藏  举报

导航