题解:AT_agc033_f [AGC033F] Adding Edges
先看若最终图上存在边
这个条件是比较烦人的,因为你没有限制
假设限制了
考虑若我们转化出一个图
若
这样不断的做,最后就可以得到我们想要的图
如何实现呢?考虑每次加入边
若存在边
反之找到第一个这样的
如何找到呢?设
每次真的可以加入
时间复杂度是多少?除去加边的过程,其他地方都是好分析的。
而加边的时候,若
那么复杂度就是
#include<bits/stdc++.h>
#define ull unsigned long long
#define ll long long
#define p_b push_back
#define m_p make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define ls k<<1
#define rs k<<1|1
#define mid ((l+r)>>1)
#define gcd __gcd
#define lowbit(x) (x&(-x))
#define ALL(x) (x).begin(),(x).end()
using namespace std;
int rd(){
int x=0,f=1; char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if (ch=='-') f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+(ch^48);
return x*f;
}
void write(int x){
if(x>9) write(x/10);
putchar('0'+x%10);
}
const int N=2005,INF=0x3f3f3f3f;
int fa[N][N],f[N][N],n,m;
vector<int> G[N];
void init(int u,int dad,int rt){
fa[rt][u]=dad;
for(auto v : G[u]) if(v^dad)init(v,u,rt);
}
queue<pii> q;
void dfs(int u,int rt,int x){
if(f[rt][u]) return q.push(m_p(u,x)),void(0);
f[rt][u]=x;
for(auto v : G[u]) if(v^fa[rt][u]) dfs(v,rt,x);
}
void ins(int x,int y){
q.push(m_p(x,y));
while(!q.empty()){
auto [u,v]=q.front();q.pop();
if(f[u][v]==v) continue;
if(f[u][v]){q.push(m_p(f[u][v],v));continue;}
if(f[v][u]){q.push(m_p(f[v][u],u));continue;}
dfs(v,u,v),dfs(u,v,u);
}
}
int ans;
void DFS(int u,int rt,int las){
if(u!=rt&&f[u][las]==las) ans++,las=u;
for(auto v : G[u]) if(v^fa[rt][u]) DFS(v,rt,las);
}
int main(){
n=rd(),m=rd();
for(int i=1,u,v;i<n;i++)u=rd(),v=rd(),G[u].p_b(v),G[v].p_b(u);
for(int i=1;i<=n;i++)init(i,0,i);
for(int i=1;i<=m;i++) ins(rd(),rd());
for(int i=1;i<=n;i++)DFS(i,i,i);
printf("%d\n",ans>>1);
return 0;
}