• 题解报告——Financial Crisis


    传送门

    【思路分析】

     这道题是一道双连通分量的板子题,我们只需要套个双联通分量,在用并查集判断连通性。

    如果两个点连通且不在一个双连通分量里,那么就只存在唯一路径,否则存在多条(值得注意的是如果一个双连通分量只有两个点,那么就GG了,要排除这种情况)。

    【代码实现】

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<vector>
      5 #include<cctype>
      6 #include<stack>
      7 using namespace std;
      8 inline void read(int &gg)
      9 {
     10     char ch;int x,f;
     11     while(!isdigit(ch=getchar())&&ch!='-'); ch=='-'?(x=0,f=-1):(x=ch-'0',f=1);
     12     while(isdigit(ch=getchar())) x=x*10+ch-'0';
     13     gg=x*f;
     14 }
     15 const int maxn=5100;
     16 struct sd{
     17     int from,to;
     18 };
     19 vector<int> link[maxn],belong[maxn],bcc[maxn];
     20 stack<sd> stk;
     21 int dfn[maxn],low[maxn],bccno[maxn],fa[maxn],cnt,n,m,q,bccnt;
     22 int find(int v)
     23 {
     24     if(fa[v]!=v) fa[v]=find(fa[v]);
     25     return fa[v];
     26 }
     27 void tarjan(int v,int ff)
     28 {
     29     dfn[v]=low[v]=++cnt;
     30     for(int i=link[v].size()-1;i>=0;i--)
     31     {
     32         int to=link[v][i];
     33         if(to==ff) continue;
     34         sd edge=(sd){v,to};
     35         if(!dfn[to])
     36         {
     37             stk.push(edge);
     38             tarjan(to,v);
     39             low[v]=min(low[v],low[to]);
     40             if(low[to]>=dfn[v])
     41             {
     42                 bcc[++bccnt].clear();
     43                 while(1)
     44                 {
     45                     sd ee=stk.top();stk.pop();
     46                     int f=ee.from,tt=ee.to;
     47                     if(bccno[f]!=bccnt)
     48                     bccno[f]=bccnt,bcc[bccnt].push_back(f),belong[f].push_back(bccnt);
     49                     if(bccno[tt]!=bccnt)
     50                     bccno[tt]=bccnt,bcc[bccnt].push_back(tt),belong[tt].push_back(bccnt);
     51                     if(f==v&&tt==to) break;
     52                 }
     53             }
     54         }
     55         else if(dfn[to]<dfn[v])
     56         {
     57             stk.push(edge);
     58             low[v]=min(low[v],dfn[to]);
     59         } 
     60     }
     61 }
     62 void remove()
     63 {
     64     cnt=bccnt=0;
     65     memset(dfn,0,sizeof(dfn));
     66     memset(low,0,sizeof(low));
     67     memset(bccno,0,sizeof(bccno));
     68     for(int i=0;i<n;i++) fa[i]=i,link[i].clear(),belong[i].clear();
     69 }
     70 int main()
     71 {
     72     int time=0;
     73     while(1)
     74     {
     75         read(n),read(m);read(q),remove();int a,b;
     76         if(n==0&&m==0&&q==0) break;
     77         for(int i=1;i<=m;i++)
     78         {
     79             read(a),read(b);
     80             link[a].push_back(b);
     81             link[b].push_back(a);
     82             int ffa=find(a),ffb=find(b);
     83             if(ffa!=ffb) fa[ffb]=ffa;
     84         }
     85         printf("Case %d:
    ",++time);
     86         for(int i=1;i<=n;i++)
     87         if(!dfn[i]) tarjan(i,0);
     88         while(q--)
     89         {
     90             read(a),read(b);
     91             if(find(a)!=find(b)) {printf("zero
    ");continue;}
     92             bool flag=0;
     93             for(int i=belong[a].size()-1;i>=0&&!flag;i--)
     94             for(int j=belong[b].size()-1;j>=0&&!flag;j--)
     95             {
     96                 if(belong[a][i]==belong[b][j]) 
     97                 if(bcc[belong[a][i]].size()>2) flag=1;
     98             }
     99             if(flag) printf("two or more
    ");
    100             else printf("one
    ");
    101         }
    102     }
    103     return 0;
    104 }
  • 相关阅读:
    早晨突然想到的几句话
    VBA-工程-找不到工程或库-解决方案
    Mysql 服务无法启动 服务没有报告任何错误
    一道有趣的面试题
    异步和多线程
    异或运算
    线性代数解惑
    全文搜索引擎 Elasticsearch (一)
    HandlerExceptionResolver统一异常处理 返回JSON 和 ModelAndView
    MySQL 20个经典面试题
  • 原文地址:https://www.cnblogs.com/genius777/p/9169438.html
Copyright © 2020-2023  润新知