QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#779262#2596. Even Forestjinzikai314TL 0ms0kbC++204.6kb2024-11-24 18:05:302024-11-24 18:05:30

Judging History

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

  • [2024-11-24 18:05:30]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [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

output:


result: