Codeforces Round #686 (Div. 3) 1454E Number of Simple Paths
Problem Description
You are given an undirected graph consisting of n vertices and n edges. It is guaranteed that the given graph is connected (i. e. it is possible to reach any vertex from any other vertex) and there are no self-loops and multiple edges in the graph.
Your task is to calculate the number of simple paths of length at least 1 in the given graph. Note that paths that differ only by their direction are considered the same (i. e. you have to calculate the number of undirected paths). For example, paths [1,2,3] and [3,2,1] are considered the same.
You have to answer t independent test cases.
Recall that a path in the graph is a sequence of vertices v1,v2,…,vk such that each pair of adjacent (consecutive) vertices in this sequence is connected by an edge. The length of the path is the number of edges in it. A simple path is such a path that all vertices in it are distinct.
Input
The first line of the input contains one integer t (1≤t≤2⋅104) — the number of test cases. Then t test cases follow.
The first line of the test case contains one integer n (3≤n≤2⋅105) — the number of vertices (and the number of edges) in the graph.
The next n lines of the test case describe edges: edge i is given as a pair of vertices ui, vi (1≤ui,vi≤n, ui≠vi), where ui and vi are vertices the i-th edge connects. For each pair of vertices (u,v), there is at most one edge between u and v. There are no edges from the vertex to itself. So, there are no self-loops and multiple edges in the graph. The graph is undirected, i. e. all its edges are bidirectional. The graph is connected, i. e. it is possible to reach any vertex from any other vertex by moving along the edges of the graph.
It is guaranteed that the sum of n does not exceed 2⋅105 (∑n≤2⋅105).
Output
For each test case, print one integer: the number of simple paths of length at least 1 in the given graph. Note that paths that differ only by their direction are considered the same (i. e. you have to calculate the number of undirected paths).
Example
input
3
3
1 2
2 3
1 3
4
1 2
2 3
3 4
4 2
5
1 2
2 3
1 3
2 5
4 3
output
6
11
18
Note
Consider the second test case of the example. It looks like that:
There are 11 different simple paths:
[1,2];
[2,3];
[3,4];
[2,4];
[1,2,4];
[1,2,3];
[2,3,4];
[2,4,3];
[3,2,4];
[1,2,3,4];
[1,2,4,3].
题意
给定一个n个点n条边的图,求有多少条不同的路径。
思路
n个点n条边,可以知道是基环树,整个图有且只有一个环,环上连接着若干棵树。
我们可以发现,只有路径上的两个端点都在同一棵树上时,该两点间的路径条数为1,否则均为2.
所以我们将这部分减去即可。设该树上的点数为m,即减去m*(m-1)。
Code
#include <bits/stdc++.h>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <iostream>
#include <queue>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> VI;
typedef vector<ll> VLL;
typedef vector<VI> VII;
typedef vector<VII> VIII;
typedef pair<int, int> PII;
#define rep(i,a,b) for(int i = (a); i <= (b); i ++)
#define per(i,a,b) for(int i = (a); i >= (b); i --)
#define mkp(a,b) make_pair(a,b)
//#define __int128 ll
const int N = 2e5 + 5;
//const int M = 30 + 5;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-9;
const double EPSS = 1e-12;
//const double PI = acos(-1);
//const double PI = 3.14;
const ll MOD = 1e9 + 7;
//const ll MOD = 998244353;
//const ll MOD = 233333333;
//const int dx[] = {-1, 1, 0, 0};
//const int dy[] = {0, 0, -1, 1};
//const int dx[] = { 1, 0, 0,-1};
//const int dy[] = { 0,-1, 1, 0};
VI G[N];
int fa[N]; //dfs时的父亲
int dfn[N], idx; //访问的时间
int loop[N], cnt; //环
int vis[N];
void get_loop(int u)
{
dfn[u] = ++ idx;
int sz = G[u].size();
for (int i = 0; i < sz; i ++)
{
int v = G[u][i];
if(v == fa[u])
continue ;
if(dfn[v])
{
if(dfn[v] < dfn[u])
continue ;
loop[++ cnt] = v;
for ( ; v != u; v = fa[v])
loop[++ cnt] = fa[v];
}
else
fa[v] = u, get_loop(v);
}
}
int dfs(int p)
{
vis[p] = 1;
int ret = 1;
int sz = G[p].size();
rep(i,0,sz-1)
{
if(vis[G[p][i]] == 1)
continue;
ret += dfs(G[p][i]);
}
return ret;
}
int main()
{
int T;
scanf("%d", &T);
while(T --)
{
int n;
scanf("%d", &n);
rep(i,1,n) vis[i] = fa[i] = dfn[i] = 0;
rep(i,1,n) G[i].clear();
cnt = idx = 0;
rep(i,1,n)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
get_loop(1);
rep(i,1,cnt) vis[loop[i]] = 1;
ll ans = 1ll * n * (n-1);
rep(i,1,cnt)
{
ll num = dfs(loop[i]);
ans -= 1ll * num * (num-1)/2;
}
printf("%I64d\n", ans);
}
return 0;
}