题目链接:http://codeforces.com/contest/979/problem/C
大致题意
给出n个点,有n-1个边将他们链接。给出x,y,当某一路径中出现x....y时,此路不通。路径(u,v)和(v,u)是不同的。
思路:一开始大神是给每个点都用BFS找出能到的点的路径,同时记录搜索的状态,但出了点小问题,估计修正了也回超时,现在给出大神思路,因为不能自己到自己所以点对数肯定是n*(n-1)这是全部的可能,那我们只要找出不可能的情况相减,那就是答案的对不对?这是肯定的,现在我们来考虑怎么找出不成立的情况,我们首先可以对x到y用dfs找到经过的点,在对x用dfs找到x可以去到那些点(这同时也是那些点可以到x。。这个结论很重要)这些点不包括x与y还有x到经历的点,共sumx,同理找到sumy,答案为n*(n-1)-sumx*sumy;为什么呢?画个图呗,首先假设有一条路径x到y是不符合的那么假设A点可以到x,那A-x-y这条路是不满足条件的,同理假设B点可以到y,那X-y-B也 不,满足。
Ac代码:
#include<bits/stdc++.h> using namespace std; int n,x,y; #define ll long long const int maxn=300000+50; vector<int>e[maxn]; bool xoy[maxn],book[maxn]; int per[maxn]; void init( ) { memset(xoy,false,sizeof(xoy)); memset(book,false,sizeof(book)); memset(per,-1,sizeof(per)); } void perdfs(int u,int fa) { per[u]=fa; if(u==y) return ; for(int i=0 ; i<e[u].size() ; i++) { int v=e[u][i]; if(v!=fa) { perdfs(v,u); } } } int dfs(int u) { book[u]=true; int sum=1; for(int i=0 ; i<e[u].size() ; i++) { int v=e[u][i]; if(!book[v]&&!xoy[v]&&v!=x&&v!=y) sum+=dfs(v); } return sum; } int main( ) { init(); scanf("%d%d%d",&n,&x,&y); for(int i=1 ; i<=n-1 ; i++) { int u,v; scanf("%d%d",&u,&v); e[u].push_back(v); e[v].push_back(u); } perdfs(x,-1); for(int i=per[y];i!=x;i=per[i]) xoy[i]=true; ll sumx=dfs(x); ll sumy=dfs(y); ll ans=(ll)n*(n-1)-(ll)(sumx*sumy); cout<<ans<<endl; return 0; }
参考出处