HDU 3749 Financial Crisis(点-双连通分量)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3749

借鉴了一位大佬的思路:https://blog.csdn.net/u013480600/article/details/31782327

题意:给你一个(保证输入无重边,无自环)无向图,然后有下面Q条询问,每条询问为:问你u点与v点之间有几条(除了首尾两点外,其他点不重复)的路径.如果有0条或1条输出0或1,如果有2条以上,输出”two or more”.

分析:
1、首先如果u点与v点不连通,直接输出0即可.(用并查集实现)
2 、然后如果u点与v点属于同一个点-双连通分量,输出two or more.(这里有特例,两点一边的点-双连通分量应该输出1)
3.、 剩下的所有情况表示u与v虽然连通,但是在不同的点-双连通分量类,直接输出1即可.
Q:如果该题仅要求u与v的不同路径边不同即可,情况又是如何呢?(这种情况更简单,只需考虑边-双连通分量即可且没有特例)

代码如下:

#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <stdio.h>
#include <string.h>
#include <stack>

using namespace std;

const int maxn=5000+5;

int n,m,q;
int dfs_clock,pre[maxn],bcc_cnt,iscut[maxn],bccno[maxn],fa[maxn];//bcc_cnt为点-双连通分量的标号  
// bccno[i]=x表示第i个顶点属于x号点双连通分量

vector<int>G[maxn],bcc[maxn],belong[maxn];//bcc[i].size()表示包含了i号 点-双连通分量的所有点   
//belong[i]表示i点属于哪些 点-双连通分量

struct Edge
{
    int u,v;
    Edge(int u,int v):u(u),v(v){};
};

stack<Edge> S;

void init()
{
    dfs_clock=bcc_cnt=0;
    memset(pre,0,sizeof(pre));
    memset(bccno,0,sizeof(bccno));
    memset(iscut,0,sizeof(iscut));
    for(int i=0; i<n; i++)
        {
            G[i].clear();
            belong[i].clear();
            fa[i]=i;
        }
}

int find_(int x)
{
    return x==fa[x]? x : fa[x]=find_(fa[x]);
}

int dfs(int u, int fa)
{
   int lowu= pre[u]= ++dfs_clock;
   int child =0;
   for(int i=0; i<G[u].size(); i++)
   {
       int v=G[u][i];
       Edge e =Edge(u,v);
       if(!pre[v])
       {
           S.push(e);
           child++;
           int lowv =dfs(v,u);
           lowu=min(lowu,lowv);
           if(lowv >=pre[u])
           {
               iscut[u]=1;
               bcc_cnt++;
               bcc[bcc_cnt].clear();
               while(true)
               {
                   Edge x=S.top();
                   S.pop();


                   if(bccno[x.u]!=bcc_cnt)
                   {
                       bcc[bcc_cnt].push_back(x.u);
                       bccno[x.u]=bcc_cnt;
                        belong[x.u].push_back(bccno[x.u]);
                   }

                   if(bccno[x.v]!=bcc_cnt)
                   {
                       bcc[bcc_cnt].push_back(x.v);
                       bccno[x.v]=bcc_cnt;
                        belong[x.v].push_back(bccno[x.v]);
                   }
                   if(x.u==u&&x.v==v)
                    break;
               }
           }
       }
       else if(pre[v]<pre[u]&&v!=fa)
       {
           S.push(e);
           lowu=min(lowu,pre[v]);
       }
   }
   if(fa<0&&child==1)
    iscut[u]=0;
   return lowu;
}

int main()
{
    int k=0;
    while(scanf("%d %d %d",&n,&m,&q)&&(n+m+q))
    {
        init();
        int u,v;
        for(int i=0; i<m; i++)
        {
            scanf("%d %d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
            int fa1,fa2;
            fa1=find_(u),fa2=find_(v);
            if(fa1!=fa2)
                fa[fa1]=fa2;
        }

        for(int i=0; i<n; i++)
        {
            if(!pre[i])
                dfs(i,-1);
        }
        printf("Case %d:\n",++k);
        for(int i=0; i<q; i++)
        {
            int flag=1;
            scanf("%d %d",&u,&v);
            int fa1,fa2;
            fa1=find_(u),fa2=find_(v);
            if(fa1!=fa2)
            {
                printf("zero\n");
                continue;
            }

            for(int i=0; i<belong[u].size(); i++)
            {
                 if(flag==0)
                    break;
                for(int j=0; j<belong[v].size(); j++)
            {
                if(belong[u][i]==belong[v][j])
                {
                    if(bcc[belong[u][i]].size()!=2)//排除特例 两点一边的情况
                    {
                     flag=0;
                     break;
                    }

                }
            }
            }
            if(flag)
                printf("one\n");
            else
                printf("two or more\n");
        }


    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36300700/article/details/81188107