제출 #62635

#제출 시각아이디문제언어결과실행 시간메모리
62635IvanC철인 이종 경기 (APIO18_duathlon)C++17
31 / 100
352 ms73140 KiB
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 3*1e5 + 10;

long long resposta;
vector<int> grafo[MAXN],tree[MAXN],pilha;
int N,M,low[MAXN],num[MAXN],dfsCount,e1[MAXN],e2[MAXN],compIdx;
int component_size,subtreeSz[MAXN],ownSize[MAXN];

long long escolhe3(int x){
	return 1LL*x*(x-1)*(x-2);
}

void get_bcc(int i){
	vector<int> membros;
	while(!pilha.empty()){
		int j = pilha.back();
		pilha.pop_back();
		membros.push_back(e1[j]);
		membros.push_back(e2[j]);
		if(j == i) break;
	}
	sort(membros.begin(),membros.end());
	membros.erase(unique(membros.begin(),membros.end()),membros.end());
	compIdx++;
	for(int v : membros){
		tree[v].push_back(compIdx);
		tree[compIdx].push_back(v);
	}
	resposta += escolhe3(membros.size());
}

void dfs_tarjan(int v,int p){

	component_size++;

	num[v] = ++dfsCount;
	low[v] = num[v];

	for(int i : grafo[v]){
		
		int u = (e1[i] != v) ? (e1[i]) : (e2[i]);

		if(u == p) continue;

		if(num[u] == 0){
			pilha.push_back(i);
			dfs_tarjan(u,v);
			if(num[v] <= low[u]){
				get_bcc(i);
			}
			low[v] = min(low[v],low[u]);
		}
		else if(num[u] < num[v]){
			low[v] = min(low[v],num[u]);
		}

	}

}

void dfs_combinatorics(int v,int p){

	ownSize[v] = (v <= N);
	subtreeSz[v] = ownSize[v];

	for(int u : tree[v]){
		if(u == p) continue;
		dfs_combinatorics(u,v);
		subtreeSz[v] += subtreeSz[u];
	}

	for(int u : tree[v]){
		if(u == p) continue;
		int c1 = subtreeSz[u];
		int c2 = ownSize[v];
		int c3 = (component_size - c1 - c2);
		resposta += 1LL*c1*c2*c3;
	}

	int c1 = (component_size - subtreeSz[v]);
	int c2 = ownSize[v];
	int c3 = (subtreeSz[v] - ownSize[v]);
	resposta += 1LL*c1*c2*c3;

	if(v > N){

		int cycle_size = (int)tree[v].size();
		int other_size = component_size - cycle_size;
		resposta += 2LL*(cycle_size - 1)*(cycle_size - 2)*other_size;

	}

}

int main(){

	scanf("%d %d",&N,&M);
	compIdx = N;
	for(int i = 1;i<=M;i++){
		scanf("%d %d",&e1[i],&e2[i]);
		grafo[e1[i]].push_back(i);
		grafo[e2[i]].push_back(i);
	}

	for(int i = 1;i<=N;i++){
		if(num[i] != 0) continue;
		component_size = 0;
		dfs_tarjan(i,-1);
		dfs_combinatorics(i,-1);
	}

	printf("%lld\n",resposta);

	return 0;

}

컴파일 시 표준 에러 (stderr) 메시지

count_triplets.cpp: In function 'int main()':
count_triplets.cpp:99:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d %d",&N,&M);
  ~~~~~^~~~~~~~~~~~~~~
count_triplets.cpp:102:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d %d",&e1[i],&e2[i]);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...