QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#553999 | #6329. Colorful Graph | ucup-team3691 | WA | 0ms | 3880kb | C++23 | 6.9kb | 2024-09-09 01:22:01 | 2024-09-09 01:22:01 |
Judging History
answer
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <map>
#include <ctime>
#include <random>
#include <cassert>
using namespace std;
using ll = long long;
const int mod = 998244353;
struct Edge {
int nxt, flow, cap;
};
struct Flow {
int n, total_flow;
vector <vector <int>> G;
vector <Edge> edge_list;
int s, d;
vector <int> prv;
bool bfs() {
queue <int> q;
for (int i = 0; i < n; i++) {
prv[i] = -1;
}
prv[s] = 0;
q.push(s);
while (!q.empty()) {
int curr = q.front();
q.pop();
for (int edge_ind : G[curr]) {
Edge curr_edge = edge_list[edge_ind];
if (prv[curr_edge.nxt] == -1 && curr_edge.flow < curr_edge.cap) {
prv[curr_edge.nxt] = edge_ind;
q.push(curr_edge.nxt);
}
}
if (prv[d] != -1) {
return 1;
}
}
return 0;
}
Flow(int _n) {
n = _n;
G.resize(n);
prv.resize(n);
s = 0;
d = n - 1;
total_flow = 0;
}
void addEdge(int x, int y, int cap) {
edge_list.push_back({y, 0, cap});
edge_list.push_back({x, 0, 0});
G[x].push_back(edge_list.size() - 2);
G[y].push_back(edge_list.size() - 1);
}
void pushFlow() {
while (bfs()) {
for (int edge_ind : G[d]) {
if (prv[edge_list[edge_ind].nxt] == -1) {
continue;
}
prv[d] = edge_ind^1;
for (int nod = d; nod != s; nod = edge_list[prv[nod]^1].nxt) {
edge_list[prv[nod]].flow++;
edge_list[prv[nod] ^ 1].flow--;
}
total_flow++;
}
}
}
void afis() {
for (int i = 0; i < edge_list.size(); i += 2) {
if (edge_list[i].cap == 1) {
continue;
}
if (edge_list[i].flow > 0) {
cout << (edge_list[i ^ 1].nxt - 1) / 2 + 1 << ' ' << (edge_list[i].nxt - 2) / 2 + 1 << ' ' << edge_list[i].flow << ' ' << edge_list[i].cap << '\n';
}
}
}
vector <vector <pair <int, int>>> getDistrib(int nr) {
vector <vector <pair <int, int>>> distribG(nr);
for (int i = 0; i < edge_list.size(); i += 2) {
if (edge_list[i].cap == 1) {
continue;
}
if (edge_list[i].flow > 0) {
distribG[(edge_list[i ^ 1].nxt - 1) / 2].push_back({(edge_list[i].nxt - 2) / 2, edge_list[i].flow});
//cerr << (edge_list[i ^ 1].nxt - 1) / 2 << ' ' << (edge_list[i].nxt - 2) / 2 << ' ' << edge_list[i].flow << '\n';
}
}
return distribG;
}
int getFlow() {
return total_flow;
}
};
struct Graph {
int n, m, nrctc;
vector <pair <int, int>> edges;
vector <vector <int>> G, revG;
vector <int> comp;
void readGraph() {
for (int i = 0; i < m; i++) {
int x, y;
cin >> x >> y;
x--, y--;
edges[i] = {x, y};
G[x].push_back(y);
revG[y].push_back(x);
}
}
void dfs1(int nod, vector <int> &used, vector <int> &ordine) {
used[nod] = 1;
for (int nxt : G[nod]) {
if (used[nxt]) {
continue;
}
dfs1(nxt, used, ordine);
}
ordine.push_back(nod);
}
void dfs2(int nod, int c) {
comp[nod] = c;
for (int nxt : revG[nod]) {
if (comp[nxt]) {
continue;
}
dfs2(nxt, c);
}
}
void computeScc() {
vector <int> used(n, 0);
vector <int> ordine;
for (int i = 0; i < n; i++) {
if (used[i]) {
continue;
}
dfs1(i, used, ordine);
}
reverse(ordine.begin(), ordine.end());
for (int i = 0; i < n; i++) {
int nod = ordine[i];
if (comp[nod]) {
continue;
}
nrctc++;
dfs2(nod, nrctc);
}
}
vector <vector <int>> simplifyEdges() {
vector <vector <int>> newG(nrctc, vector <int> ());
for (auto [x, y] : edges) {
if (comp[x] == comp[y]) {
continue;
}
newG[comp[x] - 1].push_back(comp[y] - 1);
}
for (int i = 0; i < nrctc; i++) {
sort(newG[i].begin(), newG[i].end());
newG[i].erase(unique(newG[i].begin(), newG[i].end()), newG[i].end());
}
return newG;
}
void printSolution(vector <int> &color) {
for (int i = 0; i < n; i++) {
cout << color[comp[i] - 1] << ' ';
}
}
Graph(int _n, int _m) {
n = _n;
m = _m;
edges.resize(m);
G.resize(n);
revG.resize(n);
comp.resize(n, 0);
nrctc = 0;
}
};
void solve() {
int n, m;
cin >> n >> m;
Graph sccGraph(n, m);
sccGraph.readGraph();
sccGraph.computeScc();
vector <vector <int>> G = sccGraph.simplifyEdges();
n = sccGraph.nrctc;
Flow flowGraph(2 * n + 2);
for (int i = 0; i < n; i++) {
flowGraph.addEdge(0, 2 * i + 1, 1);
flowGraph.addEdge(2 * i + 2, 2 * n + 1, 1);
flowGraph.addEdge(2 * i + 2, 2 * i + 1, 1e9);
for (int x : G[i]) {
flowGraph.addEdge(2 * i + 1, 2 * x + 2, 1e9);
}
}
flowGraph.pushFlow();
if (n >= 20) {
return;
}
vector <vector <pair <int, int>>> distribG = flowGraph.getDistrib(n);
vector <vector <int>> colors(n);
int cnt = 0;
for (int i = 0; i < n; i++) {
if (colors[i].empty()) {
cnt++;
colors[i].push_back(cnt);
}
int poz = 0;
for (auto [nod, demand] : distribG[i]) {
for (int j = 0; j < demand; j++) {
if (poz >= colors[i].size()) {
cnt++;
colors[i].push_back(cnt);
}
colors[nod].push_back(colors[i][poz]);
poz++;
}
}
}
vector <int> color(n, 0);
for (int i = 0; i < n; i++) {
color[i] = colors[i][0];
}
sccGraph.printSolution(color);
}
signed main() {
#ifdef LOCAL
freopen("test.in", "r", stdin);
freopen("test.out", "w", stdout);
#endif // LOCAL
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int nrt = 1;
//cin >> nrt;
while (nrt--) {
solve();
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3832kb
input:
5 5 1 4 2 3 1 3 2 5 5 1
output:
1 1 2 1 1
result:
ok AC
Test #2:
score: 0
Accepted
time: 0ms
memory: 3836kb
input:
5 7 1 2 2 1 4 3 5 1 5 4 4 1 4 5
output:
2 2 1 1 1
result:
ok AC
Test #3:
score: -100
Wrong Answer
time: 0ms
memory: 3880kb
input:
8 6 6 1 3 4 3 6 2 3 4 1 6 4
output:
4 4 4 5 3 4 2 1
result:
wrong answer Integer 5 violates the range [1, 4]