Codeforces Round #482 (Div. 2) C 、 Kuro and Walking Route(dfs)979C

题目链接: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;


}
View Code

参考出处

https://blog.csdn.net/amovement/article/details/80323045

posted @ 2018-05-15 18:16  shuai_hui  阅读(121)  评论(0编辑  收藏  举报