QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#98524#6329. Colorful Graphtom0727TL 2ms3696kbC++146.4kb2023-04-19 07:41:542023-04-19 07:41:58

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-04-19 07:41:58]
  • 评测
  • 测评结果:TL
  • 用时:2ms
  • 内存:3696kb
  • [2023-04-19 07:41:54]
  • 提交

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];
pii ed[maxn];

int match[maxn], vis[maxn], id = 0;
bool dfs(int i) {
    for (int j = 1; j <= n; j++) {
        if (!f[i][j] || vis[j] == id) continue;
        vis[j] = id;
        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++) {
        id++;
        dfs(i);
    }

    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";
}

详细

Test #1:

score: 100
Accepted
time: 2ms
memory: 3564kb

input:

5 5
1 4
2 3
1 3
2 5
5 1

output:

1 2 1 2 1 

result:

ok AC

Test #2:

score: 0
Accepted
time: 0ms
memory: 3628kb

input:

5 7
1 2
2 1
4 3
5 1
5 4
4 1
4 5

output:

2 2 1 2 2 

result:

ok AC

Test #3:

score: 0
Accepted
time: 2ms
memory: 3696kb

input:

8 6
6 1
3 4
3 6
2 3
4 1
6 4

output:

1 1 1 1 2 1 3 4 

result:

ok AC

Test #4:

score: -100
Time Limit Exceeded

input:

7000 6999
4365 4296
2980 3141
6820 4995
4781 24
2416 5844
2940 2675
3293 2163
3853 5356
262 6706
1985 1497
5241 3803
353 1624
5838 4708
5452 3019
2029 6161
3849 4219
1095 1453
4268 4567
1184 1857
2911 3977
1662 2751
6353 6496
2002 6628
1407 4623
425 1331
4445 4277
1259 3165
4994 1044
2756 5788
5496 ...

output:


result: