1. 程式人生 > >題解報告——Financial Crisis

題解報告——Financial Crisis

註意 stk getch 連通 type get mes AS digi

傳送門

技術分享圖片

【思路分析】

這道題是一道雙連通分量的板子題,我們只需要套個雙聯通分量,在用並查集判斷連通性。

如果兩個點連通且不在一個雙連通分量裏,那麽就只存在唯一路徑,否則存在多條(值得註意的是如果一個雙連通分量只有兩個點,那麽就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:\n",++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\n");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\n"); 100 else printf("one\n"); 101 } 102 } 103 return 0; 104 }

題解報告——Financial Crisis