codeforces-979C-Kuro and Walking Route 【dfs】

 

传送门: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\n",ans[2],ans[3]);
58     printf("%lld\n",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*/

 

posted @ 2020-03-24 21:39  L·S·D  阅读(171)  评论(0编辑  收藏  举报