Time Limit: 2 2 2 sec / Memory Limit: 1024 1024 1024 MB / Score: 400 400 400 points
An SNS has N N N users - User 1 1 1, User 2 2 2, ⋯, User N N N.
Between these N N N users, there are some relationships - M M M friendships and K K K blockships.
For each i = 1 , 2 , ⋯ , M i = 1,2,⋯,M i=1,2,⋯,M, there is a bidirectional friendship between User A i A_i Ai and User B i B_i Bi.
For each i = 1 , 2 , ⋯ , K i = 1,2,⋯,K i=1,2,⋯,K, there is a bidirectional blockship between User C i C_i Ci and User D i D_i Di.
We define User a a a to be a friend candidate for User b b b when all of the following four conditions are satisfied:
For each user i = 1 , 2 , . . . , N i = 1,2,..., N i=1,2,...,N, how many friend candidates does it have?
All values in input are integers.
2 ≤ N ≤ 1 0 5 2\le N\le 10^5 2≤N≤105
0 ≤ M ≤ 1 0 5 0\le M\le 10^5 0≤M≤105
0 ≤ K ≤ 1 0 5 0\le K\le 10^5 0≤K≤105
1 ≤ A i , B i ≤ N 1\le A_i,B_i\le N 1≤Ai,Bi≤N
A i ≠ B i A_i\ne B_i Ai=Bi
1 ≤ C i , D i ≤ N 1\le C_i,D_i\le N 1≤Ci,Di≤N
C i ≠ D i C_i\ne D_i Ci=Di
( A i , B i ) ≠ ( A j , B j ) ( i ≠ j ) (A_i,B_i)\ne (A_j,B_j)~~~~(i≠j) (Ai,Bi)=(Aj,Bj) (i=j)
( A i , B i ) ≠ ( B j , A j ) (A_i,B_i)\ne (B_j,A_j) (Ai,Bi)=(Bj,Aj)
( C i , D i ) ≠ ( D j , C j ) ( i ≠ j ) (C_i,D_i)\ne (D_j,C_j)~~~~(i≠j) (Ci,Di)=(Dj,Cj) (i=j)
( A i , B i ) ≠ ( C j , D j ) (A_i,B_i)\ne (C_j,D_j) (Ai,Bi)=(Cj,Dj)
( A i , B i ) ≠ ( D j , C j ) (A_i,B_i)\ne (D_j,C_j) (Ai,Bi)=(Dj,Cj)
Input is given from Standard Input in the following format:
N M K
A1 B1
A2 B2
...
AM BM
C1 D1
C2 D2
...
CK DK
Print the answers in order, with space in between.
4 4 1
2 1
1 3
3 2
3 4
4 1
0 1 0 1
There is a friendship between User 2 and 3, and between 3 and 4. Also, there is no friendship or blockship between User 2 and 4. Thus, User 4 is a friend candidate
for User 2.
However, neither User 1 or 3 is a friend candidate for User 2, so User 2 has one friend candidate
.
5 10 0
1 2
1 3
1 4
1 5
3 2
2 4
2 5
4 3
5 3
4 5
0 0 0 0 0
Everyone is a friend of everyone else and has no friend candidate
.
10 9 3
10 1
6 7
8 2
2 5
8 4
7 3
10 9
6 4
5 8
2 6
7 5
3 1
1 3 5 4 3 3 3 3 1 0
把整个朋友圈拆分为一个个连通子图,再对于每个用户用对应子图节点数-1(本身)-子图中的跟当前用户有friendship
和blockship
的逐个得到结果
代码也在这里
注意:只能使用C++>=11的编译器才能通过编译。(我提交时用的是 C++14 (GCC 5.4.1) 编译器)
#include
#include
#include
#define maxn 100005
using namespace std;
typedef vector<int>* Graph;
int n, m, k, graphnum[maxn], subgraphsize[maxn];
vector<int> friends[maxn], block[maxn];
template <typename T>
void bfs(const Graph& G, int v, T visit, bool* visited)
{
queue<int> q;
q.push(v);
while(!q.empty())
{
int x = q.front(); q.pop();
if(visited[x]) continue;
visited[x] = true;
visit(x);
for(int it: G[x]) q.push(it);
}
}
void splitgraph(const Graph& G) // Returns: number of subgraphs
{
int cnt = 0;
auto vis = [&cnt](int v) {
subgraphsize[graphnum[v] = cnt] ++;
};
bool* visited = new bool[n];
// split into subgraphs
for(int i=0; i<n; i++) visited[i] = false;
for(int i=0; i<n; i++)
if(!visited[i])
{
bfs(G, i, vis, visited);
cnt ++;
}
delete[] visited;
}
int main(int argc, char** argv)
{
// Input
scanf("%d%d%d", &n, &m, &k);
for(int i=0; i<m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
friends[--x].push_back(--y);
friends[y].push_back(x);
}
for(int i=0; i<k; i++)
{
int x, y;
scanf("%d%d", &x, &y);
block[--x].push_back(--y);
block[y].push_back(x);
}
// Split firends into subgraphs
splitgraph(friends);
// Count bad (friendships & blockships in current subgraph & itself) for each vertex
int* badcnt = new int[n];
for(int i=0; i<n; i++) badcnt[i] = 1; // 1, not 0! (the vertex itself)
for(int i=0; i<n; i++)
{
// Blockship
for(int it: block[i])
if(it > i && graphnum[it] == graphnum[i])
badcnt[i] ++, badcnt[it] ++;
// Friendship
for(int it: friends[i])
if(it > i && graphnum[it] == graphnum[i])
badcnt[i] ++, badcnt[it] ++;
}
for(int i=0; i<n; i++) printf("%d ", subgraphsize[graphnum[i]] - badcnt[i]);
putchar('\n');
delete[] badcnt;
return 0;
}