传送门:codeforces-979C-Kuro and Walking Route
题意:有n个城市,n-1条路,给出x,y两个城市,问不经过从x到y的道路有多少条
通过找规律我们可以发现,不经过的话,就少了1,2,3到4,5,6的路,总数是A(6,2)=30,少的路是3*3=9,那把他推广一下,答案就是ans=n*(n-1)-x*y,x是以y为根的x的子树的节点个数,y是以x为根的y的子树的节点个数
这样问题就清晰了,一遍dfs把从x到y的路线标记上,然后再来两遍dfs分别求节点数就可以了
注意n的范围不开long long可能会炸
标记的时候要注意如果不是从x到y的路径要回溯把标记消掉,而且找到了就break,否则回溯的时候会起冲突,嗯卡我挺久的
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int N=1e6+9; 5 const int inf=1e9; 6 int vis[300009]; 7 ll deep=0,flag=0; 8 ll x,y,ans[5]={0}; 9 vector<ll>ve[300009]; 10 void dfs(ll xx) 11 { 12 if(xx==y) 13 { 14 flag=1; 15 return ; 16 } 17 int l=ve[xx].size(); 18 for(int i=0;i<l;i++) 19 { 20 if(!vis[ve[xx][i]]) 21 { 22 ll u=ve[xx][i]; 23 vis[u]=1; 24 dfs(u); 25 if(flag) break; 26 vis[u]=0; 27 } 28 } 29 } 30 void dfs_(ll x,int cnt) 31 { 32 if(vis[x]==2) return ; 33 vis[x]=2; 34 ans[cnt]++; 35 int l=ve[x].size(); 36 for(int i=0;i<l;i++) 37 { 38 ll u=ve[x][i]; 39 if(vis[u]!=1) dfs_(u,cnt); 40 } 41 } 42 int main() 43 { 44 ll n,a,b; 45 scanf("%lld%lld%lld",&n,&x,&y); 46 for(int i=1;i<n;i++) 47 { 48 scanf("%lld%lld",&a,&b); 49 ve[a].push_back(b); 50 ve[b].push_back(a); 51 } 52 vis[x]=1; 53 dfs(x); 54 // for(int i=1;i<=n;i++) printf("%d ",vis[i]); 55 dfs_(x,2); 56 dfs_(y,3); 57 printf("%lld %lld ",ans[2],ans[3]); 58 printf("%lld ",n*(n-1)-ans[2]*ans[3]); 59 return 0; 60 } 61 /*6 3 4 1 3 3 2 3 4 4 5 4 6*/