Pagini recente » Cod sursa (job #928705) | Cod sursa (job #505312) | Cod sursa (job #1188364) | Cod sursa (job #891373) | Cod sursa (job #1043647)
#include <algorithm>
#include <fstream>
#include <iostream>
#include <queue>
#include <set>
#include <vector>
using namespace std;
ifstream fin("count.in");
ofstream fout("count.out");
const int MAX_N = 30100;
const int MAX_M = 60100;
int N, M;
pair<int, int> edges[MAX_M];
vector<int> graph[MAX_N];
bool removed_edge[MAX_M];
int node_degree[MAX_N];
pair<int, int> max_clique;
struct set_cmp {
bool operator() (const int &lhs, const int &rhs) const {
return (node_degree[lhs] < node_degree[rhs]);
}
};
set<int> nodes;
void read_input();
void solve();
void print_output();
pair<int, int> find_max_clique();
pair<int, int> compute_clique(int node);
bool adjacent(int a, int b);
int other(int edge, int node);
void update_pair(pair<int, int> &p, int val);
int main() {
read_input();
solve();
print_output();
return 0;
}
void read_input() {
fin >> N >> M;
for (int i = 1; i <= M; ++i) {
fin >> edges[i].first;
fin >> edges[i].second;
graph[edges[i].first].push_back(i);
graph[edges[i].second].push_back(i);
}
}
void solve() {
for (int i = 1; i <= N; ++i) {
node_degree[i] = graph[i].size();
nodes.insert(i);
}
max_clique = find_max_clique();
}
void print_output() {
fout << max_clique.first << ' ' << max_clique.second;
}
pair<int, int> find_max_clique() {
pair<int, int> result = make_pair(0, 0);
for (int step = 1; step <= N; ++step) {
int node = *nodes.begin();
pair<int, int> clique = compute_clique(node);
if (clique.first > result.first) {
result = clique;
} else if (clique.first == result.first) {
result.second += clique.second;
}
nodes.erase(nodes.begin());
for (auto x: graph[node]) {
if (removed_edge[x]) continue;
int neighbour = other(x, node);
nodes.erase(nodes.find(neighbour));
removed_edge[x] = true;
node_degree[neighbour] -= 1;
nodes.insert(neighbour);
}
}
return result;
}
pair<int, int> compute_clique(int node) {
pair<int, int> result = make_pair(1, 1);
int n = graph[node].size();
for (int a = 0; a < n; ++a) {
if (removed_edge[graph[node][a]]) continue;
update_pair(result, 2);
for (int b = a + 1; b < n; ++b) {
if (removed_edge[graph[node][b]]) continue;
if (adjacent(other(graph[node][a], node), other(graph[node][b], node))) {
update_pair(result, 3);
for (int c = b + 1; c < n; ++c) {
if (removed_edge[graph[node][c]]) continue;
if (adjacent(other(graph[node][b], node), other(graph[node][c], node))) {
update_pair(result, 4);
}
}
}
}
}
return result;
}
inline void update_pair(pair<int, int> &p, int val) {
if (val > p.first) {
p = make_pair(val, 1);
} else if (val == p.first) {
p.second += 1;
}
}
inline bool adjacent(int a, int b) {
for (auto x: graph[a]) {
if (removed_edge[x]) continue;
if (other(x, a) == b) return true;
}
return false;
}
inline int other(int edge, int node) {
return edges[edge].first + edges[edge].second - node;
}