이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
#define DIM 100007
long long res, cnt[DIM], sz[2*DIM], pnt[2*DIM], n, m, u, v, vis[2*DIM], used[DIM], tin[DIM], tmin[DIM], timer, comps;
set<long long> vec[2*DIM];
set<long long> p;
vector<pair<long long, long long> > edge;
void dfs(long long v, long long par)
{
used[v]=1;
tin[v]=tmin[v]=++timer;
long long ch_cnt=0;
for(auto to : vec[v])
{
if(to==par) continue;
if(used[to]==0)
{
dfs(to, v);
ch_cnt++;
tmin[v]=min(tmin[v], tmin[to]);
if(par!=-1 && tmin[to]>=tin[v])
{
p.insert(v);
pnt[v]=1;
}
}
else tmin[v]=min(tmin[v], tin[to]);
}
if(par==-1 && ch_cnt>1)
{
p.insert(v);
pnt[v]=1;
}
return;
}
void find_comp(long long v)
{
vis[v]=comps;
cnt[comps]++;
for(auto to : vec[v])
{
if(vis[to]!=0) continue;
find_comp(to);
}
return;
}
void buildtree(long long v, long long par)
{
if(v<=n) sz[v]+=1;
sz[v]+=cnt[v-n];
for(auto to : vec[v])
{
if(to==par) continue;
sz[to]+=sz[v];
buildtree(to, v);
}
return;
}
void get_res(long long v)
{
for(int i=1; i<=2*n; i++) sz[i]=0;
buildtree(v, -1);
/*printf("%lld:\n", v);
for(int i=1; i<=2*n; i++) printf("%lld ", sz[i]);
printf("\n");*/
for(auto u : p)
{
if(sz[u]<2 || u==v) continue;
res+=sz[v]*(sz[u]-2);
}
for(int i=1; i<=comps; i++)
{
if(sz[i+n]<2 || i+n==v) continue;
res+=sz[v]*(sz[i+n]-2)*cnt[i];
}
long long ns=vec[v].size();
for(int i=0; i<ns; i++)
{
res+=sz[v]*(sz[v]-1);
}
res+=sz[v]*(sz[v]-1)*(sz[v]-2);
return;
}
int main()
{
scanf("%lld%lld", &n, &m);
for(int i=0; i<m; i++)
{
scanf("%lld%lld", &u, &v);
vec[v].insert(u);
vec[u].insert(v);
}
for(int i=1; i<=n; i++)
{
if(used[i]==0) dfs(i, -1);
}
for(auto v : p)
{
for(auto to : vec[v])
{
vec[to].erase(v);
edge.push_back({v, to});
}
vec[v].clear();
}
for(int i=1; i<=n; i++)
{
if(vis[i]==0 && pnt[i]==0)
{
comps++;
find_comp(i);
}
}
for(auto P : edge)
{
v=P.first;
u=P.second;
if(pnt[u])
{
vec[v].insert(u);
vec[u].insert(v);
continue;
}
vec[v].insert(vis[u]+n);
vec[vis[u]+n].insert(v);
}
for(auto u : p) get_res(u);
for(int i=1; i<=comps; i++) get_res(i+n);
printf("%lld", res);
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
count_triplets.cpp: In function 'int main()':
count_triplets.cpp:97:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
97 | scanf("%lld%lld", &n, &m);
| ~~~~~^~~~~~~~~~~~~~~~~~~~
count_triplets.cpp:100:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
100 | scanf("%lld%lld", &u, &v);
| ~~~~~^~~~~~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |