题解报告——Financial Crisis
Posted genius777
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解报告——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 }
以上是关于题解报告——Financial Crisis的主要内容,如果未能解决你的问题,请参考以下文章
HDU 3749 Financial Crisis(点-双连通分量)