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. android平台获取手机IMSI,IMEI ,序列号,和 手机号的方法

    1)获取运营商sim卡imsi号, String IMSI =android.os.SystemProperties.get( android.telephony.TelephonyPropertie ...

  2. Android中的事件分发机制总结

    Android 的事件分发机制 一.View的事件分发总结: View的onTouchEvent和OnTouch区别  还是以自定义的TestButton为例. 我们可以通过重写onTouchEven ...

  3. 利用dijkstra算法规划线路

    # dijkstra# 1.在数据库内预先存放了北京市内最新的道路节点,选用优化了得dijkstra算法进行线路规划.    当输入起点和终点后,会计算出最短的路径.同时还能选择查看路径经过的道路节点 ...

  4. 数据结构及算法分析(0)——引论

          引论提到算法递归的概念,递归在很多算法中都会出现.所谓递归,当一个函数用它自己来定义的时候就称为递归.     递归调用有两大要素: 基准情况. 递归调用.     并非所有的数学递归函数 ...

  5. ubuntu_scrapy 安装

    1:install pip python-dev    sudo apt-get install python-dev    sudo apt-get install libevent-dev     ...

  6. D3中path各指令的含义

    svg.append('path').attr({ id: 'mypath', d: 'M50 100Q350 50 350 250Q250 50 50 250' }) path 的指令有: 指令 参 ...

  7. IIS经典模式和集成模式在管道模型中的不同

    问题: 有时候我们配置IIS后可能运行提示以下错误: HTTP 错误 500.23 - Internal Server Error 检测到在集成的托管管道模式下不适用的 ASP.NET 设置. 其中由 ...

  8. C#+ArcEngine 序列化和反序列化AE对象

    http://www.cnblogs.com/jindin/archive/2009/07/23/1529695.html 在AE开发过程,总是要将某些对象暂时存储起来,像element,layer, ...

  9. HW--字符串加解密

    package t0817; import java.util.Scanner; public class StringEncrypt { public static void main(String ...

  10. JavaScript高级程序设计(九):基本概念----语句的特殊点

    一.Label语句.break/continue语句和for循环语句的结合使用: 1.Label语句可以在代码中添加标签,以便将来使用.语法: label:statment   eg: start:f ...