• LOJ-10102(求A到B之间的割点)


    题目链接:传送门

    思路:求A到B之间必要的中间节点

    条件:(1)只有一条路径经过中间节点;(low[B]>=num[u]&&num[v]<=num[B],没有从B到u的路径)

    (2)中间节点不能和A,B重合(u!=A&&num[v]<=num[B],先v后B)

    (3)中间节点一定是割点(num[u]<=low[v])

    然后就是Tarjan的模板了。

    参考文章:传送门

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    const int maxn = 100100;
    int num[maxn],vis[maxn],low[maxn],tim,A,B,ans;
    vector <int> vc[maxn];
    void Init()
    {
        memset(num,0,sizeof(num));
        memset(vis,0,sizeof(vis));
        memset(low,0,sizeof(low));
        tim=0;ans=9999999;
    }
    void Tarjan(int u,int pre)
    {
        num[u]=low[u]=++tim;
        int i,v;
        for(i=0;i<vc[u].size();i++){
            v=vc[u][i];
            if(!num[v]){
                Tarjan(v,u);
                low[u]=min(low[u],low[v]);
                if(u!=A&&num[u]<=low[v]&&num[v]<=num[B]&&low[B]>=num[u]) ans=min(ans,u); 
            }
            else if(pre!=v) low[u]=min(low[u],num[v]);
        }
    }
    int main(void)
    {
        int n,m,i,j,x,y;
        while(~scanf("%d",&n)){
            Init();
            while(scanf("%d%d",&x,&y)&&(x+y)){
                vc[x].push_back(y);
                vc[y].push_back(x);
            }
            scanf("%d%d",&A,&B);
            Tarjan(A,-1);
            if(ans<=n) printf("%d
    ",ans);
            else printf("No solution
    ");
        }
        return 0;
    } 
    View Code
  • 相关阅读:
    boost::asio::error的用法浅析
    boost::asio::buffer
    sqlserver2008安装图解
    WCF 聊天室程序代码详细讲解教程
    C#中使用Property Grid(属性面板)控件
    TXT>Access 使用DAO数据源!(VB Code)
    读取INI文件 VbCode
    Pet Shop 4
    模式行为型
    C#编程规范
  • 原文地址:https://www.cnblogs.com/2018zxy/p/10360398.html
Copyright © 2020-2023  润新知