QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#98560 | #6329. Colorful Graph | tom0727 | WA | 0ms | 3620kb | C++14 | 6.4kb | 2023-04-19 07:53:14 | 2023-04-19 07:53:15 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#if __cplusplus >= 201103L
struct pairhash {
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
template<class T, class U>
size_t operator() (const pair<T,U> &p) const {
static const uint64_t FIXED_RANDOM = (uint64_t)chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(p.first + FIXED_RANDOM) ^ splitmix64(p.second+ FIXED_RANDOM);
}
};
struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = (uint64_t)chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());
inline int randint(int l, int r) {
return uniform_int_distribution<int>(l,r)(rng);
}
inline double randdouble(double l, double r) {
return uniform_real_distribution<double>(l,r)(rng);
}
#endif
#ifndef ONLINE_JUDGE
# define LOG(x) (cerr << #x << " = " << (x) << endl)
#else
# define LOG(x) 0
#endif
#define fastio ios::sync_with_stdio(false); cin.tie(0);
#define ll long long
#define ull unsigned long long
#define ll128 __int128_t
#define PI 3.14159265358979323846
#define abs(a) ((a>0)?a:-(a))
#define pii pair<int,int>
#define pll pair<ll,ll>
const long double pi = acos(-1.0);
const long double eps = (double)1e-8;
const int mod = 1e9+7;
template<class T>
T qpow(T a, int b) {
T res = 1;
while (b) {
if (b & 1) res *= a;
a *= a;
b >>= 1;
}
return res;
}
int norm(int x) {
if (x < 0) {
x += mod;
}
if (x >= mod) {
x -= mod;
}
return x;
}
struct Z {
int x;
Z(int x = 0) : x(norm(x)) {}
Z(ll x) : x(norm((int)(x % mod))) {}
int val() const {
return x;
}
Z operator-() const {
return Z(norm(mod - x));
}
Z inv() const {
assert(x != 0);
return qpow(*this, mod - 2);
}
Z &operator*=(const Z &rhs) {
x = (ll)(x) * rhs.x % mod;
return *this;
}
Z &operator+=(const Z &rhs) {
x = norm(x + rhs.x);
return *this;
}
Z &operator-=(const Z &rhs) {
x = norm(x - rhs.x);
return *this;
}
Z &operator/=(const Z &rhs) {
return *this *= rhs.inv();
}
friend Z operator*(const Z &lhs, const Z &rhs) {
Z res = lhs;
res *= rhs;
return res;
}
friend Z operator+(const Z &lhs, const Z &rhs) {
Z res = lhs;
res += rhs;
return res;
}
friend Z operator-(const Z &lhs, const Z &rhs) {
Z res = lhs;
res -= rhs;
return res;
}
friend Z operator/(const Z &lhs, const Z &rhs) {
Z res = lhs;
res /= rhs;
return res;
}
friend std::istream &operator>>(std::istream &is, Z &a) {
ll v;
is >> v;
a = Z(v);
return is;
}
friend std::ostream &operator<<(std::ostream &os, const Z &a) {
return os << a.val();
}
};
const int maxn = 7002;
const int maxm = 1e5+55;
int n, m;
vector<int> adj[maxn];
struct Tarjan {
int dfn[maxn], low[maxn], id, from[maxn], scc = 0, sz[maxn];
bool in[maxn]; // instack or not
int st[maxn], tail = -1;
void dfs(int u) {
in[u] = 1;
st[++tail] = u;
dfn[u] = low[u] = ++id;
for (int to : adj[u]) {
if (dfn[to] && in[to]) low[u] = min(low[u], dfn[to]); // 要记得在栈内
if (!dfn[to]) {
dfs(to);
low[u] = min(low[u], low[to]);
}
}
if (dfn[u] == low[u]) {
from[u] = ++scc;
sz[scc] = 1;
while (tail >= 0 && st[tail] != u) {
int cur = st[tail];
from[cur] = from[u];
sz[scc]++;
tail--;
in[cur] = 0; // 记得这里,将在栈中的标记去掉
}
tail--;
in[u] = 0; // 记得这里,将在栈中的标记去掉
}
}
// 跑tarjan
void solve() {
for (int i = 1; i <= n; i++) {
if (!dfn[i]) dfs(i);
}
}
} tj;
bitset<maxn> f[maxn], can;
pii ed[maxn];
int match[maxn], id = 0;
bool dfs(int i) {
bitset<maxn> F = (f[i] & can);
for (int j = F._Find_first(); j < F.size(); j = F._Find_next(j)) {
can[j] = 0;
if (!match[j] || dfs(match[j])) {
match[j] = i;
return 1;
}
}
return 0;
}
int color[maxn], pre[maxn], nxt[maxn], ans[maxn];
int main() {
fastio;
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int u, v; cin >> u >> v;
adj[u].push_back(v);
ed[i] = {u, v};
}
tj.solve();
for (int i = 1; i <= m; i++) {
int u = ed[i].first, v = ed[i].second;
int fu = tj.from[u], fv = tj.from[v];
if (fu == fv) continue;
f[fu][fv] = 1;
// printf("fu = %d, fv = %d\n",fu,fv);
}
int N = tj.scc;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (f[j][i]) f[j] |= f[i];
}
}
// int ans = 0;
for (int i = 1; i <= N; i++) {
if (dfs(i)) can.set();
}
int c = 0;
for (int i = 1; i <= N; i++) {
if (match[i]) {
nxt[match[i]] = i;
pre[i] = match[i];
}
}
for (int i = 1; i <= N; i++) {
if (!pre[i]) {
int j = i;
++c;
while (j) {
color[j] = c;
j = nxt[j];
}
}
}
for (int i = 1; i <= n; i++) {
ans[i] = color[tj.from[i]];
cout << ans[i] << " ";
}
// assert(c == ans);
cout << "\n";
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 3620kb
input:
5 5 1 4 2 3 1 3 2 5 5 1
output:
3 5 2 1 4
result:
wrong answer Integer 3 violates the range [1, 2]