QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#779262 | #2596. Even Forest | jinzikai314 | TL | 0ms | 0kb | C++20 | 4.6kb | 2024-11-24 18:05:30 | 2024-11-24 18:05:30 |
answer
#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<set>
#define int long long
#define pb push_back
using namespace std;
const int N = 2.5e5 + 5;
const int M = 4e5 + 5;
const int DEBUG_MODE = 0;
inline int read(){
int n=0, f=1; char ch=getchar();
for(; !isdigit(ch); ch=getchar()) if(ch=='-') f=-1;
for(; isdigit(ch); ch=getchar()) n=n*10+ch-48;
return n*f;
}
bool Bst;
struct Edge{
int nxt, to;
}g[M], G[M], gg[M<<1];
int T;
int n, m;
int U[M], V[M];
int head[N], ent;
int Head[N], Ent;
int HEAD[N], ENT;
int dfn[N], low[N], dfc;
int Dfn[N], Low[N], Dfc;
stack<int> stk;
bool vis[N];
int scc[N], siz[N], sc;
vector<int> dcc[N];
int dc;
int indeg[N];
int rt;
set<int> mp[N];
set<int> st[N];
int f[N];
bool Bed;
void CLEAR(){
for(int i=1; i<=n; i++) {
f[i] = indeg[i] = head[i] = Head[i] = HEAD[i] = dfn[i] = low[i] = scc[i] = Dfn[i] = Low[i] = siz[i] = vis[i] = 0;
mp[i].clear();
st[i].clear();
}
for(int i=1; i<=ent; i++) g[i].nxt = g[i].to = 0;
for(int i=1; i<=Ent; i++) G[i].nxt = G[i].to = 0;
for(int i=1; i<=ENT; i++) gg[i].nxt = gg[i].to = 0;
for(int i=1; i<=dc; i++) vector<int>().swap(dcc[i]);
ent = Ent = ENT = dfc = Dfc = sc = dc = 0;
}
void add_edge(int u, int v){
g[++ent].nxt = head[u];
g[ent].to = v;
head[u] = ent;
}
void add_nodir_edge(int u, int v){
gg[++ENT].nxt = HEAD[u];
gg[ENT].to = v;
HEAD[u] = ENT;
}
void add_SCC_edge(int u, int v){
if(DEBUG_MODE) printf("SCCEDGE %lld -> %lld\n", u, v);
++indeg[v];
G[++Ent].nxt = Head[u];
G[Ent].to = v;
Head[u] = Ent;
}
void tarjan(int u){
low[u] = dfn[u] = ++dfc;
stk.push(u); vis[u] = true;
for(int i=head[u]; i; i=g[i].nxt){
int v = g[i].to;
if(!dfn[v]){
tarjan(v);
low[u] = min(low[u], low[v]);
} else if(vis[v]){
low[u] = min(low[u], dfn[v]);
}
}
if(dfn[u] == low[u]){
++sc;
if(DEBUG_MODE) printf("--- SCC #%lld:\n", sc);
while(stk.top() != u){
if(DEBUG_MODE) printf("%lld\n", stk.top());
scc[stk.top()] = sc;
++siz[sc];
vis[stk.top()] = 0;
stk.pop();
}
if(DEBUG_MODE) printf("%lld\n", stk.top());
scc[stk.top()] = sc;
++siz[sc];
vis[stk.top()] = 0;
stk.pop();
}
}
void Tarjan(int u) {
Dfn[u] = Low[u] = ++Dfc, stk.push(u);
if(u == rt && HEAD[u] == 0){
dcc[++dc].pb(u);
return;
}
for(int i=HEAD[u]; i; i=gg[i].nxt){
int v = gg[i].to;
if(!Dfn[v]){
Tarjan(v);
Low[u] = min(Low[u], Low[v]);
if(Low[v] >= Dfn[u]){
// if (++f > 1 || u != rt) cut[u] = true;
++dc;
if(DEBUG_MODE) printf("--- DCC #%lld:\n", dc);
int tpv;
do {
if(DEBUG_MODE) printf("%lld\n", stk.top());
dcc[dc].pb(tpv = stk.top());
stk.pop();
}
while(tpv != v);
if(DEBUG_MODE) printf("%lld\n", u);
dcc[dc].pb(u);
}
} else Low[u] = min(Low[u], Dfn[v]);
}
}
int topo_sort(){
queue<int> q;
int ans = 0;
for(int i=1; i<=sc; i++){
if(!indeg[i]) q.push(i);
f[i] = siz[i];
}
while(!q.empty()){
int u = q.front(); q.pop();
for(int i=Head[u]; i; i=G[i].nxt){
int v = G[i].to;
--indeg[v];
f[v] += f[u];
if(!indeg[v]) {
for(auto x: mp[v]) f[v] -= f[x];
q.push(v);
}
}
}
for(int i=1; i<=sc; i++) {
// if(DEBUG_MODE) printf("f[%lld] = %lld\n", i, f[i]);
ans += siz[i]*f[i];
}
return ans;
}
signed main(){
// printf("Memory = %f MB\n", (&Bst-&Bed)/1024.0/1024.0);
T = read();
while(T--){
n = read(), m = read();
CLEAR();
for(int i=1; i<=m; i++){
U[i] = read(), V[i] = read();
add_edge(U[i], V[i]);
add_nodir_edge(U[i], V[i]);
add_nodir_edge(V[i], U[i]);
st[U[i]].insert(V[i]);
}
for(int i=1; i<=n; i++) if(!dfn[i]) tarjan(i);
for(int i=1; i<=n; i++) if(!Dfn[i]) rt = i, Tarjan(i);
for(int i=1; i<=m; i++) if(scc[U[i]] != scc[V[i]]) add_SCC_edge(scc[U[i]], scc[V[i]]);
for(int i=1; i<=dc; i++){
int cnt0 = 0, cnt2 = 0;
int cnt0id = -1, cnt2id = -1;
int len = dcc[i].size();
if(len <= 2) continue;
for(int j=0; j<len; j++){
int x = dcc[i][j];
int lst = dcc[i][(j-1+len)%len];
int nxt = dcc[i][(j+1)%len];
int deg = (st[x].count(lst) + st[x].count(nxt));
if(deg == 0) ++cnt0, cnt0id = x;
if(deg == 2) ++cnt2, cnt2id = x;
}
// printf("cnt0 = %lld, cnt2 = %lld, cnt0id = %lld, cnt2id = %lld\n", cnt0, cnt2, cnt0id, cnt2id);
if(cnt0 == 1 && cnt2 == 1) mp[scc[cnt0id]].insert(scc[cnt2id]);
}
printf("%lld\n", topo_sort());
}
}
详细
Test #1:
score: 0
Time Limit Exceeded
input:
4 1 2 2 3 3 4