QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#104495 | #6329. Colorful Graph | yangjl | TL | 0ms | 3508kb | C++20 | 4.7kb | 2023-05-10 21:03:03 | 2023-05-10 21:03:10 |
Judging History
answer
#include<iostream>
#include<cmath>
#include<cstring>
#include<cassert>
#include<string>
#include<queue>
#include<deque>
#include<stack>
#include<algorithm>
#include<unordered_map>
#include<map>
#include<vector>
#include<set>
#include<unordered_set>
#include<bitset>
#include<climits>
#include<numeric>
#include<functional>
#include<iomanip>
#include<random>
#ifdef YJL
#include<debug.h>
#else
#define debug(args...)0
#define debug_n(a,n)0
#endif
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int n,m;
namespace Tarjan {
struct ty {
int t,l,next;
} edge[int(2e6)+10];
int en,head[N];
void initGraph(int n) {
fill_n(head+1,n,-1),en=0;
}
void addEdge(int x,int y,int z=0) {
edge[en]={y,z,head[x]};
head[x]=en++;
}
int dfn[N], low[N], dn;
int sta[N], insta[N], top;
int color[N], cn;
void tarjan(int u) {
dfn[u]=low[u]=++dn;
sta[++top]=u;
insta[u]=1;
for (int i=head[u]; ~i; i=edge[i].next) {
int v=edge[i].t;
if (!dfn[v]) {
tarjan(v);
low[u]=min(low[u], low[v]);
} else if (insta[v])// 返祖边和横插边
low[u]=min(low[u], dfn[v]);
}
if (dfn[u]==low[u]) {
++cn;
for (int v=-1; v!=u;) {
v=sta[top--];
insta[v]=0;
color[v]=cn;
}
}
}
void converge(int n) {
fill_n(dfn+1,n,0), dn=cn=0;
for(int i=1; i<=n; ++i)
if(!dfn[i])
tarjan(i);
}
auto newGraph() {
vector<pair<int,int>> e;
for(int u=1; u<=n; ++u) {
for(int _i=head[u]; ~_i; _i=edge[_i].next) {
int v=edge[_i].t;
if(color[u]!=color[v])
e.emplace_back(color[u],color[v]);
}
}
return e;
}
}
namespace NetFlow {
using T=int;
const T INF=T(1)<<(sizeof(T)*8-2);
const int _V=10000+10;
const int _E=200000*2+10;
int s0=_V-1,t0=s0-1;
int head[_V],en;
struct ty {
int t, next;
T l;
} edge[_E];
void initGraph() {
memset(head, -1, sizeof(head)), en=0;
}
void addEdge(int x, int y, T z=0) {
edge[en]= {y, head[x], z};
head[x]=en++;
if(en&1) addEdge(y, x);
}
int dis[_V];
bool bfs(int s,int t) {
memset(dis,-1,sizeof dis);
queue<int> q;
dis[s]=0;
q.push(s);
while(q.size()) {
int u=q.front();
q.pop();
for (int i=head[u]; ~i; i=edge[i].next) {
int v=edge[i].t;
if(dis[v]==-1&&edge[i].l>0) {
dis[v]=dis[u]+1;
q.push(v);
}
}
}
return dis[t]!=-1;
}
T dfs(int u, T flow,int t) {
if(u==t) return flow;
T ans=flow;
for (int i=head[u]; ~i&&ans; i=edge[i].next) {
int v=edge[i].t;
if (dis[v]==dis[u]+1&&edge[i].l>0) {
T tmp=dfs(v, min(edge[i].l, ans), t);
edge[i].l-=tmp;
edge[i^1].l+=tmp;
ans-=tmp;
}
}
if(ans==flow) dis[u]=-1;
return flow-ans;
}
T dinic(int s,int t) {
T ans=0;
while(bfs(s,t)) ans+=dfs(s,INF,t);
return ans;
}
int find_next(int u) {
for(int _i=head[u]; ~_i; _i=edge[_i].next) {
int v=edge[_i].t;
if(_i%2==0 && edge[_i^1].l && v!=s0 && v!=t0)
return v;
}
return -1;
}
}
using namespace NetFlow;
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin>>n>>m;
Tarjan::initGraph(n);
while(m--) {
int u,v;
cin>>u>>v;
Tarjan::addEdge(u,v);
}
Tarjan::converge(n);
auto edg=Tarjan::newGraph();
debug_n(Tarjan::color+1,n);
debug(edg);
int nn=Tarjan::cn;
initGraph();
for(int i=1; i<=nn; ++i) {
addEdge(s0,i,1);
addEdge(i+nn,t0,1);
}
for(auto [u,v]:edg) {
addEdge(u,v+nn,INF);
addEdge(u,v,INF);
}
int flow=dinic(s0,t0);
debug(nn-flow);
vector<int> nxt(nn+1),col(nn+1);
for(int u=1,tot=0; u<=nn; ++u) {
int s=u;
while(s>=1 && s<=nn) {
s=find_next(s);
debug(s);
}
debug(u,s);
if(s==-1) {
col[u]=++tot;
nxt[u]=-1;
}else nxt[u]=s-nn;
}
for(int i=1; i<=n; ++i) {
if(col[i]) continue;
int j=i;
while(col[j]==0)
j=nxt[j];
int c=col[j];
for(j=i; !col[j]; j=nxt[j])
col[j]=c;
}
for(int i=1; i<=n; ++i)
cout<<col[Tarjan::color[i]]<<" ";
return 0;
}
/*
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3508kb
input:
5 5 1 4 2 3 1 3 2 5 5 1
output:
2 1 1 2 2
result:
ok AC
Test #2:
score: -100
Time Limit Exceeded
input:
5 7 1 2 2 1 4 3 5 1 5 4 4 1 4 5