您的位置:首页 > 其它

HDU 6016 Count the Sheep

2017-02-26 14:34 501 查看
比赛时是用右边的点存了他连向的左边的点所能连向的右边的点数。

感觉怪怪的。

赛后题解时用遍历每条中间的边做的,我的做法相当于遍历每条开始的边做的。

题解的做法好看多了。

我的做法:

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

typedef long long ll;
const int MAXN = 1e5+5;
vector<int> G[2*MAXN];
ll a[2*MAXN];

int main() {
int T;
scanf("%d", &T);
while(T--) {
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
for(int i = 0; i <= n+m; i++) G[i].clear();
while(k--) {
int x, y;
scanf("%d%d", &x, &y);
y += n;
G[x].push_back(y);
G[y].push_back(x);
}
for(int i = n+1; i <= n+m; i++) {
a[i] = 0;
for(int j = 0; j < G[i].size(); j++) {
int v = G[i][j];
a[i] += (ll)G[v].size()-1LL;
}
}
ll ans = 0;
for(int i = 1; i <= n; i++) {
for(int j = 0; j < G[i].size(); j++) {
int u = G[i][j];
ans += 2LL*(a[u]-(ll)G[i].size()+1LL);
}
}
printf("%I64d\n", ans);
}
return 0;
}

改成题解的做法:

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

typedef long long ll;
const int MAXN = 1e5+5;
vector<int> G[2*MAXN];
ll a[2*MAXN];

int main() {
int T;
scanf("%d", &T);
while(T--) {
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
for(int i = 0; i <= n+m; i++) G[i].clear(), a[i] = 0;
while(k--) {
int x, y;
scanf("%d%d", &x, &y);
y += n;
G[x].push_back(y);
G[y].push_back(x);
a[x]++, a[y]++;
}
ll ans = 0;
for(int i = 1; i <= n; i++) {
for(int j = 0; j < G[i].size(); j++) {
int u = G[i][j];
ans += (a[u]-1LL)*(a[i]-1LL);
}
}
printf("%I64d\n", 2LL*ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: