https://ac.nowcoder.com/acm/contest/1057/C
#include<bits/stdc++.h> using namespace std; #define MAXN 100005 int T;//最大深度 int n,m; int cnt,first[MAXN<<1],nxt[MAXN<<1]; int u[MAXN<<1],v[MAXN<<1]; void add(int a,int b){ ++cnt; nxt[cnt]=first[a];first[a]=cnt; u[cnt]=a,v[cnt]=b; } int deep[MAXN<<1],f[MAXN][30]; void bfs(int x) { queue<int> que; que.push(x); deep[x]=1; while(que.size()) { int cur=que.front(); que.pop(); for(int i=first[cur];i;i=nxt[i]) { int to=v[i]; if(deep[to])continue; deep[to]=deep[cur]+1; f[to][0]=cur; for(int j=1;j<=T;j++){ f[to][j]=f[f[to][j-1]][j-1]; } que.push(to); } } } inline int lca(int x,int y) { if(deep[x]>deep[y]) swap(x,y); for(int i=T;i>=0;i--) { if(deep[f[y][i]]>=deep[x]) y=f[y][i]; } if(x==y) return x; for(int i=T;i>=0;i--) { if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; } return f[x][0]; } int val[MAXN]; void dfs(int cur,int fa){ for(int i=first[cur];i;i=nxt[i]){ int to=v[i]; if(to==fa)continue; dfs(to,cur); val[cur]+=val[to]; } } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<n;i++){ int a,b; scanf("%d%d",&a,&b); add(a,b);add(b,a); } T=(int)(log(n)/log(2))+1;//最大深度 bfs(1); for(int i=1;i<=m;i++) { int a,b; scanf("%d%d",&a,&b); val[a]++,val[b]++; val[lca(a,b)]-=2; } dfs(1,0); int ans=0; for(int i=2;i<=n;i++){ if(val[i]==0)ans+=m;//随便断一条非树边 if(val[i]==1)++ans;//只有断此条非树边 } cout<<ans<<endl; return 0; }
#include<bits/stdc++.h> using namespace std; #define MAXN 200010 int edgex[MAXN],edgey[MAXN]; int n,m; int cnt,first[MAXN<<1],nxt[MAXN<<1]; int u[MAXN<<1],v[MAXN<<1]; void add(int a,int b){ ++cnt; nxt[cnt]=first[a];first[a]=cnt; u[cnt]=a,v[cnt]=b; } vector<int> query[MAXN],query_id[MAXN]; void addQuery(int x,int y,int id){ query[x].push_back(y),query_id[x].push_back(id); query[y].push_back(x),query_id[y].push_back(id); } int f[MAXN]; int getf(int x){ if(x==f[x])return x; return f[x]=getf(f[x]); } void merge(int a,int b){ int fa=getf(a),fb=getf(b); if(fa!=fb)f[fb]=fa; } int vis[MAXN],deep[MAXN],ans[MAXN]; void tarjan(int cur){ vis[cur]=1; for(int i=first[cur];i;i=nxt[i]){ int to=v[i]; if(vis[to])continue; deep[to]=deep[cur]+1; tarjan(to); merge(cur,to); } for(int i=0;i<query[cur].size();i++){ int to=query[cur][i],id=query_id[cur][i]; if(vis[to]==2){ int lca=getf(to); //ans[id]=min(ans[id],deep[cur]+deep[to]-2*deep[lca]);//lca距离 ans[id]=lca;//lca根结点 } } vis[cur]=2; } int val[MAXN]; void dfs(int cur,int fa){ for(int i=first[cur];i;i=nxt[i]){ int to=v[i]; if(to==fa)continue; dfs(to,cur); val[cur]+=val[to]; } } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<n;i++){ int a,b; scanf("%d%d",&a,&b); add(a,b);add(b,a); } for(int i=1;i<=m;i++){ int a,b; scanf("%d%d",&a,&b); if(a==b)ans[i]=b;//不能漏 addQuery(a,b,i);addQuery(b,a,i); edgex[i]=a;edgey[i]=b; } for(int i=1;i<=n;i++)f[i]=i; tarjan(1); for(int i=1;i<=m;i++){ ++val[edgex[i]];++val[edgey[i]]; val[ans[i]]-=2; } dfs(1,0); int ans=0; for(int i=2;i<=n;i++){ if(val[i]==0)ans+=m;//随便断一条非树边 if(val[i]==1)++ans;//只有断此条非树边 } cout<<ans<<endl; return 0; }
来源:https://blog.csdn.net/Roar__/article/details/102760521