POJ 3417 Network
每条额外的边加入到图中,会导致树上一条路径成环,假设没有其余边,那么要将新图分成两部分,如果想删一条成环路径上的边,那么必须把这条额外边也删除。
因此每条额外边加入时,只需将环上的边+1。最后看看每条边被加了几次,被加了x次,也就是说删除这条边,至少还要删除x条边才能被分成两半,如果一次都没有被加,意味着这条边删了就分成两半了,对答案的贡献为m;如果被加了一次,那么对答案的贡献为1;如果被加的次数超过1,那么对答案没有贡献。
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-8; void File() { freopen("D:\\in.txt","r",stdin); freopen("D:\\out.txt","w",stdout); } inline int read() { char c = getchar(); while(!isdigit(c)) c = getchar(); int x = 0; while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } return x; } const int maxn=100000+10; int n,m,cnt,h[maxn],f[maxn]; struct Edge{int to,nx;}e[2*maxn]; bool flag[maxn]; void AddEdge(int u,int v) { e[cnt].to=v; e[cnt].nx=h[u]; h[u]=cnt++; } void dfs(int x) { flag[x]=1; for(int i=h[x];i!=-1;i=e[i].nx) { if(flag[e[i].to]) continue; dfs(e[i].to); f[x]=f[x]+f[e[i].to]; } } int F[2*maxn],B[2*maxn],pos[maxn]; int rmq[maxn*2][20],done; void DFS(int u,int p,int dep) { F[++done]=u,B[done]=dep; pos[u]=done; for(int son=h[u];son!=-1;son=e[son].nx) { int v=e[son].to; if(v==p)continue; DFS(v,u,dep+1); F[++done]=u,B[done]=dep; } } void initRMQ() { for(int i=1;i<=done;i++)rmq[i][0]=i; for(int j=1;(1<<j)<=done;j++) for(int i=1;i+(1<<j)-1<=done;i++) if(B[rmq[i][j-1]]<B[rmq[i+(1<<(j-1))][j-1]])rmq[i][j]=rmq[i][j-1]; else rmq[i][j]=rmq[i+(1<<(j-1))][j-1]; } int LCA(int a,int b) { a=pos[a],b=pos[b]; if(a>b)swap(a,b); int k=log(1.0+b-a)/log(2.0); if(B[rmq[a][k]]<B[rmq[b-(1<<k)+1][k]])return F[rmq[a][k]]; else return F[rmq[b-(1<<k)+1][k]]; } int main() { scanf("%d%d",&n,&m); done=cnt=0; memset(h,-1,sizeof h); for(int i=0;i<n-1;i++) { int u,v; scanf("%d%d",&u,&v); AddEdge(u,v); AddEdge(v,u); } DFS(1,1,0); initRMQ(); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); f[u]++; f[v]++; f[LCA(u,v)]-=2; } dfs(1); int ans=0; for(int i=2;i<=n;i++) { if(f[i]==0) ans=ans+m; else if(f[i]==1) ans=ans+1; } printf("%d\n",ans); return 0; }