[UPC | 山东省赛] The Largest SCC | Tarjan强连通分量瞎搞 + 状态还原

简介: 题目描述Consider a directed graph with N (1 <= N <= 1000) vertices and M (0 <=M <= 20000) edges. The edges are numbered from 1 to M and the vertices are numbered from 1 to N. Now I will make ONE edge bidirectional, and you are to tell me the number of vertices of the largest strong connected components

题目描述


Consider a directed graph with N (1 <= N <= 1000) vertices and M (0 <=M <= 20000) edges. The edges are numbered from 1 to M and the vertices are numbered from 1 to N. Now I will make ONE edge bidirectional, and you are to tell me the number of vertices of the largest strong connected components in the new graph.The largest strong connected components is the strong connected components which has the most vertices. After the operation, I will change the edge back. There will be up to Q (1 <= Q <= 20000) such queries.


输入


At the firest of the input comes an integer t, indicates the testcases to follow.

The first line of each case contains three numbers N, M and Q. Then there will be M lines, each of them contains two numbers a,b (a! = b; 1 <= a; b <= N) means there is a directed edge between a and b. The last of each case contains Q lines, each of them contains one integer q, means the edge numbered q will be change to bidirectional. There will not be duplicated edges.


输出


For every query, output one line contains only one integer number, which is the number of vertices of the biggest strong connected components.


样例输入


1
5 4 2
1 2
2 3
1 3
4 1
1
3


样例输出


2
3


题意:


给出n 个点m 条边的图,边为有向边,q 此查询,如果每次将第k 条边变为双向边,问改变这一条边为双向边之后,图中的最大的强连通分量里面包含多少个点


思路1(wa):

首先求出SCC,将在同一个强连通分量里面的点用并查集维护在一起(此时顺便找出一个最大值),然后再加边[变为双向边其实就是加了一条从原来的终点向之前的起点的一条边]的时候,查看边的两个端点是不是在同一个强连通分量中,如果在同一个强连通分量中,就直接输出原来的最大值,如果说不是在同一个强连通分量中,就将两个强连通分量的大小与之前的最大值求一个最大进行输出,

这样是不对的,因为改变一条边之后,可能影响的不是两个端点所在的连通块,所以说这里不能够用这种方法来处理

应该是:

思路2(ac):

因为点的个数只有1000 ,所以我们直接每次加入一条新的边之后,重新进行Tarjan

比如说:第k条边是u->v 的,那么说我们应该加入一从v->u的边,这样一来,然后我们从u点开始重新进行Tarjan,因为在原始的图中,是u->v的,这样一来我们只需要记录影响的大小和原先最大值的大小取一个最大值即可

在进行Tarjan的时候,如果是一开始的预处理,是可以加入新的强连通分量的,但是在处理q此询问的时候,不可以有新的强连通分量产生,因为不能对原图进行修改,(每次询问都是单独的),而对于新加入的边,也要在下一次操作之前去掉,但是强连通分量的大小是可以改变的,每次找到最大的size


Code:


int n, m, q;
struct node {
  int to, nex;
} e[maxn << 2];
int cnt, head[maxn], dfc;
int dfn[maxn], low[maxn], pos[maxn];
int num[maxn], vis[maxn];
int cntSCC, ans;
void init() {
  cnt = dfc = cntSCC = 0;
  for(int i = 1; i <= n; i++) {
    head[i] = -1;
    pos[i] = vis[i] = 0;
  }
}
void add(int u, int v) {
  e[cnt].to = v;
  e[cnt].nex = head[u];
  head[u] = cnt ++;
}
stack<int> stk;
int mx,premx;
void Tarjan(int x) {
  int u = x;
  dfn[u] = low[u] = ++ dfc;
  vis[u] = 1;
  stk.push(u);
  for(int i=head[u]; ~i; i=e[i].nex) {
    int v = e[i].to;
    if(!dfn[v]) {
      Tarjan(v);
      low[u] = min(low[u],low[v]);
    } else if(vis[v]) {
      low[u] = min(low[u],dfn[v]);
    }
  }
  int tp;
  if(low[u] == dfn[u]) {
    ++ cntSCC;
    do{
      tp = stk.top();
      stk.pop();
      vis[tp] = 0;
      if(vis[0]) pos[tp] = cntSCC;
      num[cntSCC] ++;
      mx = max(mx,num[cntSCC]);
    }while(tp != u);
  }
}
typedef pair<int,int> PII;
vector<PII> save;
void ClearStack(){
  while(stk.size()) stk.pop();
}
int main() {
  int _ = read;
  while(_ --) {
    n = read,m = read,q = read;
    init();
    save.clear();
    memset(dfn,0,sizeof dfn);
    memset(low,0,sizeof low);
    memset(vis,0,sizeof vis);
    memset(num,0,sizeof num);
    vis[0] = 1;
    for(int i = 1; i <= m; i++) {
      int u = read, v = read;
      add(u, v);
      save.push_back({u,v});
    }
    ClearStack();
    mx = 0,premx = 0;
    for(int i=1; i<=n; i++) {
      if(!dfn[i]) Tarjan(i);
    }
    premx = mx;
//    cout << mx << endl;
//    cout << premx << endl;
    vis[0] = 0;
    while(q --) {
      int id = read - 1;
      PII eg = save[id];
      int u = eg.first,v = eg.second;
//      cout << u <<"  ->  " << v<< endl;
      if(pos[u] == pos[v]) {
        printf("%d\n",mx);
        continue;
      }
      add(v,u);
      memset(dfn,0,sizeof dfn);
//      memset(low,0,sizeof low);
      dfc = 0;
      ClearStack();
      Tarjan(u);
      printf("%d\n",mx);
      mx = premx;
      head[v] = e[--cnt].nex;
    }
  }
  return 0;
}




目录
相关文章
|
安全 算法 Go
有向图的强联通分量(SCC)Tarjan算法
有向图的强联通分量(SCC)Tarjan算法
184 0
|
6天前
|
存储 人工智能 调度
阿里云吴结生:高性能计算持续创新,响应数据+AI时代的多元化负载需求
在数字化转型的大潮中,每家公司都在积极探索如何利用数据驱动业务增长,而AI技术的快速发展更是加速了这一进程。
|
1天前
|
存储 人工智能 大数据
阿里云吴结生:高性能计算持续创新,响应数据+AI时代的多元化负载需求
在数字化转型的大潮中,每家公司都在积极探索如何利用数据驱动业务增长,而AI技术的快速发展更是加速了这一进程。
|
8天前
|
存储 人工智能 弹性计算
对话阿里云吴结生:AI时代,云上高性能计算的创新发展
在阿里云智能集团副总裁,弹性计算产品线负责人、存储产品线负责人 吴结生看来,如今已经有很多行业应用了高性能计算,且高性能计算的负载正呈现出多样化发展的趋势,“当下,很多基础模型的预训练、自动驾驶、生命科学,以及工业制造、半导体芯片等行业和领域都应用了高性能计算。”吴结生指出。
|
5天前
|
机器学习/深度学习 人工智能 弹性计算
阿里云AI服务器价格表_GPU服务器租赁费用_AI人工智能高性能计算推理
阿里云AI服务器提供多种配置选项,包括CPU+GPU、CPU+FPGA等组合,支持高性能计算需求。本文汇总了阿里云GPU服务器的价格信息,涵盖NVIDIA A10、V100、T4、P4、P100等多款GPU卡,适用于人工智能、机器学习和深度学习等场景。详细价格表和实例规格见文内图表。
|
3月前
|
机器学习/深度学习 人工智能 弹性计算
阿里云AI服务器价格表_GPU服务器租赁费用_AI人工智能高性能计算推理
阿里云AI服务器提供多样化的选择,包括CPU+GPU、CPU+FPGA等多种配置,适用于人工智能、机器学习和深度学习等计算密集型任务。其中,GPU服务器整合高性能CPU平台,单实例可实现最高5PFLOPS的混合精度计算能力。根据不同GPU类型(如NVIDIA A10、V100、T4等)和应用场景(如AI训练、推理、科学计算等),价格从数百到数千元不等。详情及更多实例规格可见阿里云官方页面。
224 1
|
5月前
|
存储 弹性计算 网络协议
阿里云hpc8ae服务器ECS高性能计算优化型实例性能详解
阿里云ECS的HPC优化型hpc8ae实例搭载3.75 GHz AMD第四代EPYC处理器,配备64 Gbps eRDMA网络,专为工业仿真、EDA、地质勘探等HPC工作负载设计。实例提供1:4的CPU内存配比,支持ESSD存储和IPv4/IPv6,操作系统限于特定版本的CentOS和Alibaba Cloud Linux。ecs.hpc8ae.32xlarge实例拥有64核和256 GiB内存,网络带宽和eRDMA带宽均为64 Gbit/s。适用于CFD、FEA、气象预报等场景。
|
5月前
|
存储 弹性计算 网络协议
阿里云高性能计算HPC优化实例商业化发布详解
基于云的高性能计算(Cloud HPC),与传统HPC相比更加灵活、高效。
|
6月前
|
存储 机器学习/深度学习 网络协议
阿里云高性能计算实例规格族有哪些?各自特点、适用场景介绍
阿里云高性能计算是的阿里云服务器ECS的架构之一,高性能计算实例规格族主要应用于各种需要超高性能、网络和存储能力的应用场景,例如人工智能、机器学习、科学计算、地质勘探、气象预报等场景。高性能计算实例规格族有高性能计算优化型实例规格族hpc8ae、高性能计算优化型实例规格族hpc7ip、计算型超级计算集群实例规格族sccc7等。下面是阿里云高性能计算实例规格族特点、适用场景介绍。
阿里云高性能计算实例规格族有哪些?各自特点、适用场景介绍
|
6月前
|
存储 机器学习/深度学习 并行计算
阿里云服务器X86计算、Arm计算、GPU/FPGA/ASIC、高性能计算架构区别
在我们选购阿里云服务器的时候,云服务器架构有X86计算、ARM计算、GPU/FPGA/ASIC、弹性裸金属服务器、高性能计算可选,有的用户并不清楚他们之间有何区别,本文主要简单介绍下不同类型的云服务器有何不同,主要特点及适用场景有哪些。
阿里云服务器X86计算、Arm计算、GPU/FPGA/ASIC、高性能计算架构区别

热门文章

最新文章