QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#98671 | #6329. Colorful Graph | CSU2023 | TL | 0ms | 0kb | C++14 | 4.7kb | 2023-04-19 20:02:30 | 2023-04-19 20:02:34 |
Judging History
answer
#include <bits/stdc++.h>
template <class T>
inline void read(T &res)
{
char ch; bool flag = false; res = 0;
while (ch = getchar(), !isdigit(ch) && ch != '-');
ch == '-' ? flag = true : res = ch ^ 48;
while (ch = getchar(), isdigit(ch))
res = res * 10 + ch - 48;
flag ? res = -res : 0;
}
template <class T>
inline void nonnegative_put(T x)
{
if (x > 9)
nonnegative_put(x / 10);
putchar(x % 10 + 48);
}
template <class T>
inline void put(T x)
{
if (x < 0)
x = -x, putchar('-');
nonnegative_put(x);
}
template <class T>
inline void CkMin(T &x, T y) {x > y ? x = y : 0;}
template <class T>
inline void CkMax(T &x, T y) {x < y ? x = y : 0;}
template <class T>
inline T Min(T x, T y) {return x < y ? x : y;}
template <class T>
inline T Max(T x, T y) {return x > y ? x : y;}
template <class T>
inline T Abs(T x) {return x < 0 ? -x : x;}
template <class T>
inline T Sqr(T x) {return x * x;}
//call Sqr((ll)x) when the type of returned value is "long long".
using std::map;
using std::set;
using std::pair;
using std::bitset;
using std::string;
using std::vector;
using std::complex;
using std::multiset;
using std::priority_queue;
typedef long long ll;
typedef long double ld;
typedef complex<ld> com;
typedef pair<int, int> pir;
const ld pi = acos(-1.0);
const ld eps = 1e-8;
const int Maxn = 1e9;
const int Minn = -1e9;
const int mod = 998244353;
const int N = 14e3 + 5;
vector<int> e[N], re[N];
int sre[N], ans[N], ind[N], dfn[N], low[N], stk[N], col[N];
bool ins[N];
bitset<N> vis[N];
int T_data, n, m, C, top, tis;
const int M = 7e4 + 5;
int nxt[M], to[M], cap[M], adj[N], que[N], cur[N], lev[N];
int src, des, qr, T = 1;
inline void linkArc(int x, int y, int w)
{
nxt[++T] = adj[x]; adj[x] = T; to[T] = y; cap[T] = w;
nxt[++T] = adj[y]; adj[y] = T; to[T] = x; cap[T] = 0;
}
inline bool Bfs()
{
for (int x = 1; x <= des; ++x)
cur[x] = adj[x], lev[x] = -1;
// 初始化具体的范围视建图而定,这里点的范围为 [1,n]
que[qr = 1] = src;
lev[src] = 0;
for (int i = 1; i <= qr; ++i)
{
int x = que[i], y;
for (int e = adj[x]; e; e = nxt[e])
if (cap[e] > 0 && lev[y = to[e]] == -1)
{
lev[y] = lev[x] + 1;
que[++qr] = y;
if (y == des)
return true;
}
}
return false;
}
inline int Dinic(int x, int flow)
{
if (x == des)
return flow;
int y, delta, res = 0;
for (int &e = cur[x]; e; e = nxt[e])
if (cap[e] > 0 && lev[y = to[e]] > lev[x])
{
delta = Dinic(y, Min(flow - res, cap[e]));
if (delta)
{
cap[e] -= delta;
cap[e ^ 1] += delta;
res += delta;
if (res == flow)
break ;
//此时 break 保证下次 cur[x] 仍有机会增广
}
}
if (res != flow)
lev[x] = -1;
return res;
}
inline int maxFlow()
{
int res = 0;
while (Bfs())
res += Dinic(src, Maxn);
return res;
}
inline void Tarjan(int x)
{
dfn[x] = low[x] = ++tis;
stk[++top] = x;
ins[x] = true;
for (int y : e[x])
if (!dfn[y])
{
Tarjan(y);
CkMin(low[x], low[y]);
}
else if (ins[y])
CkMin(low[x], dfn[y]);
if (dfn[x] == low[x])
{
int y;
++C;
do
{
y = stk[top--];
ins[y] = false;
col[y] = C;
}while (y != x);
}
}
inline void dfs(int x)
{
ans[x] = tis;
for (int y : re[x])
if (ind[y])
{
--ind[y];
dfs(y);
return ;
}
}
int main()
{
read(n); read(m);
for (int i = 1, x, y; i <= m; ++i)
{
read(x); read(y);
e[x].emplace_back(y);
}
for (int i = 1; i <= n; ++i)
if (!dfn[i])
Tarjan(i);
for (int x = 1; x <= n; ++x)
{
for (int y : e[x])
if (col[x] != col[y])
vis[col[x]][col[y]] = 1;
e[x].clear();
}
src = (C << 1) | 1, des = src + 1;
for (int x = 1; x <= C; ++x)
{
linkArc(src, x, 1);
linkArc(x + C, des, 1);
linkArc(x + C, x, Maxn);
for (int y = 1; y <= C; ++y)
if (vis[x][y])
linkArc(x, y + C, Maxn);
}
int _ans = maxFlow();
for (int x = 1; x <= C; ++x)
for (int e = adj[x]; e; e = nxt[e])
if (!(e & 1) && to[e] > C && to[e] < src && to[e] - C != x && cap[e ^ 1] > 0)
{
for (int t = 1; t <= cap[e ^ 1]; ++t)
re[x].emplace_back(to[e] - C);
ind[to[e] - C] += cap[e ^ 1];
}
tis = 0;
for (int x = 1; x <= C; ++x)
sre[x] = re[x].size();
for (int t = 1; t <= C; ++t)
{
for (int x = 1; x <= C; ++x)
while (sre[x] > ind[x])
{
++tis;
int u = x;
ans[u] = tis;
while (sre[u])
{
int v = re[u][sre[u]];
re[u].pop_back();
u = v;
ans[v] = tis;
--ind[v];
}
}
}
for (int x = 1; x <= C; ++x)
if (!ans[x])
ans[x] = ++tis;
for (int i = 1; i <= n; ++i)
put(ans[col[i]]), putchar(' ');
putchar('\n');
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Time Limit Exceeded
input:
5 5 1 4 2 3 1 3 2 5 5 1