Financial Crisis

题意:给一个图,包含N ( 3 <= N <= 5000 )个点, M ( 0 <= M <= 10000 )条边 and Q ( 1 <= Q <= 1000 )次查询.查询:两个点是否是点-双连通;

点-双连通:两点至少存在两条"点不重复"的路径;简称双连通(biconnected);

思路:直接调用dfs求割点的算法,其实也是Tarjan发明的,就是在判断出一个割点之后,就把栈S中该双连通分量的所有点(就在栈顶)insert到同一个集合中;

注意:一个点可以属于多个双连通分类,所以bccno数组其实只是一个防止重复insert同一个点,在set中可以除去。并且注意初始化各种数组即序号(这样都TLE几次)

PS:原本使用链式向前星来存储边,可是发现在hd里竟然比直接vector建图还慢。。(一脸茫然);并且开始使用stack<PII> 直接MLE了,可是看别人直接使用库栈。。

#include<iostream>
#include<sstream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<stack>
#include<set>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a)) const int MAXN = ;
int low[MAXN],pre[MAXN],dfs_clock,bcc_cnt;
int bccno[MAXN];//看点属于哪个双连通分量;
set<int> bcc[MAXN];//存储每一个双连通分量的点的标号;
typedef pair<int,int> PII;
#define A first
#define B second
#define pb push_back
PII S[MAXN<<];//存储边,从中取点
vector<int> e[MAXN];
int top;
int dfs(int u,int fa)
{
int lowu = pre[u] = ++dfs_clock;
int child = ;
rep0(i,,e[u].size()){
int v = e[u][i];
PII e = PII{u,v};
if(!pre[v]){
S[++top] = e;
child++;
int lowv = dfs(v,u);
lowu = min(lowu,lowv);//以子节点的low来更新u的low函数;
if(lowv >= pre[u]){ //表示u-v为桥
bcc[++bcc_cnt].clear();
for(;;){
PII x = S[top--];
if(bccno[x.A] != bcc_cnt){bcc[bcc_cnt].insert(x.A);bccno[x.A] = bcc_cnt;}//就是为了不重复加点
if(bccno[x.B] != bcc_cnt){bcc[bcc_cnt].insert(x.B);bccno[x.B] = bcc_cnt;}
if(x.A == u && x.B == v) break;//根据加入的顺序知,正好对应;
}
}
}
else if(v != fa && pre[v] < pre[u]){
S[++top] = e;
lowu = min(lowu,pre[v]);
}
}
return low[u] = lowu;
}
int f[MAXN];
int Find(int a)
{
return a==f[a]?f[a]:f[a]=Find(f[a]);
}
char ans[][] = {"zero","one","two or more"};
int main()
{
int N,M,Q,kase = ;
while(scanf("%d%d%d",&N,&M,&Q) == && N+M+Q){
rep0(i,,N){
f[i] = i;
e[i].clear();//直接vector建图
}
int u,v;
rep0(i,,M){
scanf("%d%d",&u,&v);
e[u].pb(v);e[v].pb(u);
u = Find(u),v = Find(v);
if(u != v) f[v] = u;
}
bcc_cnt = dfs_clock = top = ;
MS0(pre);MS0(bccno);
rep0(i,,N)if(pre[i] == )
dfs(i,-);
printf("Case %d:\n",kase++);
rep0(i,,Q){
int ret;
scanf("%d%d",&u,&v);
if(Find(u) != Find(v)) ret = ;
else{
ret = ;
rep1(j,,bcc_cnt){
if(bcc[j].find(u) != bcc[j].end() && bcc[j].find(v) != bcc[j].end()&&bcc[j].size() > )
ret = ;
}
}
printf("%s\n",ans[ret]);
}
}
return ;
}

HDU 3749 Financial Crisis的更多相关文章

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

    Because of the financial crisis, a large number of enterprises go bankrupt. In addition to this, oth ...

  2. HDU 3749 Financial Crisis 经济危机(点双连通分量)

    题意: 给一个图n个点m条边(不一定连通),接下来又q个询问,询问两个点是为“不相连”,“仅有一条路径可达”,“有两条及以上的不同路径可达”三种情况中的哪一种.注:两条以上的路径指的是路径上的点连1个 ...

  3. HDU 3749 Financial Crisis (点双连通+并查集)

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

  4. HDU 1064 Financial Management

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1064 解题报告:用来凑个题数吧,看题的时间比过题的时间多的多,就是输入12个浮点数,然后输出平均数,只 ...

  5. 高效算法——Most financial institutions 贪心 H

    H - 贪心 Crawling in process... Crawling failed Time Limit:3000MS     Memory Limit:0KB     64bit IO Fo ...

  6. HDU 4667 Building Fence(2013多校7 1002题 计算几何,凸包,圆和三角形)

    Building Fence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)To ...

  7. HDU 4667 Building Fence(求凸包的周长)

    A - Building Fence Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u ...

  8. OUC_Summer Training_ DIV2_#12(DP1) 723

    这一次是做练习,主要了解了两个算法,最大子矩阵和,最长上升子序列. 先看题好啦. A - To The Max Time Limit:1000MS     Memory Limit:32768KB   ...

  9. 备战noip week8

    POJ1144 网络 description: 给出一张\(N\)个点的无向图,求其中割点的个数 data range: \(N\le 100\) solution: 一道模板题(但是读入实在是把我恶 ...

随机推荐

  1. 原 Debian设置开机自动启动与关闭

    发表于1年前(2013-01-08 13:01)   阅读(2380) | 评论(0) 2人收藏此文章, 我要收藏 赞0 开机自动启动 update-rc.d chkconfig 熟悉debian系统 ...

  2. Paginator

    Paginator There are several ways to paginate items. The simplest is by using the paginate method on ...

  3. oracle字段类型

    oracle 字段类型CHAR    固定长度字符串    最大长度2000    bytes              VARCHAR2    可变长度的字符串    最大长度4000    byt ...

  4. eclipse安装插件的方法,以python为例子

    一 转载自:http://www.cnblogs.com/linzhenjie/articles/2639113.html 1.基本需求 1.Eclipse 集成开发环境下载 http://115.c ...

  5. APP运营干货分享

    从移动互联网市场总监岗位出发,从几个方面来阐述移动互联网部门如何制定一份运营推广策划案,至于关于移动互联网,移动电商是大趋势这些虚的.空泛的文字,不展开说了. 一.竞品分析 1.选择竞品,做好定位(选 ...

  6. 在centos中php 在连接mysql的时候,出现Can't connect to MySQL server on 'XXX' (13)

    原文连接:http://hi.baidu.com/zwfec/item/64ef5ed9bf1cb3feca0c397c 红色的是命令 SQLSTATE[HY000] [2003] Can't con ...

  7. Java内存分配全面浅析(转)

           原文引自CSDN:        本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java.这类文章网上有很多,但大多比较零碎.本文从认知过程角度出发,将带给读者一个 ...

  8. 仿php的日期函数,asp时间处理函数

    <% '****************************** '时间处理函数 'FormatDate(Str,DateTime) 'Str 字符串,DateTime 时间 '返回类型为字 ...

  9. 如何用java实现使用电子邮件控制你的电脑

    上两天看到一篇文章,用python实现电子邮件控制电脑的有趣的小程序 python 实现微信控制电脑     python版的视频教程 但是苦于自己没接触过python于是想到能不能用java实现,于 ...

  10. How Indexes Are Stored

    reference:  http://docs.oracle.com/cd/B28359_01/server.111/b28318/schema.htm#CHDJGADJ 当创建索引的时候,Oracl ...