题意:

给你一个n个点,m条有向边的图,然后给你k个操作,每次把第i个边改变成无向边。然后求该图的强连通块里面点数最多的值

思路:

首先bfs求出每个点可达的边,然后tarjan求出强连通块。每次改变边时,如果这条边的两个端点在同一连通块(u,v),直接输出最多。如果不在同一连通块,首先加上这两个连通块的个数组成新的连通块,然后枚举i u->i ,i>v满足,然后i不属于u或者v的连通块,然后加上该连通块数量即可。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>#define CL(arr, val)    memset(arr, val, sizeof(arr))#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define ll __int64
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("din.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout);#define M 20010
#define N 1010
using namespace std;
const int mod = 1000000007;bool isok[N][N];
struct node
{int u,v;
}nd[M];struct side
{int v;int next;
}g[M];int dfn[N],low[N];
int belong[N],stk[N];
bool ins[N];
int cnt,top,idx;int head[N],ct;bool vt[N];
int num[N];
int n,m,k;
int ans;void init()
{for (int i = 0; i <= n; ++i){dfn[i] = low[i] = belong[i] = -1;ins[i] = false;head[i] = -1;num[i] = 0;}cnt = idx = ct = top = 0;
}
void add(int u,int v)
{g[ct].v = v;g[ct].next = head[u];head[u] = ct++;
}
void bfs(int s)
{queue<int> Q;vt[s] = true;Q.push(s);while (!Q.empty()){int u = Q.front(); Q.pop();for (int i = head[u]; i != -1; i = g[i].next){int v = g[i].v;if (!vt[v]){vt[v] = true;isok[s][v] = true;Q.push(v);}}}
}
void tarjan(int u)
{int i,v;low[u] = dfn[u] = ++idx;stk[++top] = u; ins[u] = true;for (i = head[u]; i != -1; i = g[i].next){v = g[i].v;if (dfn[v] == -1){tarjan(v);low[u] = min(low[u],low[v]);}else if (ins[v]){low[u] = min(low[u],dfn[v]);}}if (dfn[u] == low[u]){cnt++;do{v = stk[top--];ins[v] = false;belong[v] = cnt;num[cnt]++;}while (v != u);ans = max(ans,num[cnt]);}
}
int main()
{
//    Read();int T,i,j;scanf("%d",&T);while (T--){scanf("%d%d%d",&n,&m,&k);init();for (i = 1; i <= m; ++i){scanf("%d%d",&nd[i].u,&nd[i].v);add(nd[i].u,nd[i].v);}CL(isok,false);//标记两点是否可达//找出每个每个点可达的点for (i = 1; i <= n; ++i){for (j = 1; j <= n; ++j) vt[j] = false;bfs(i);}ans = 0;for (i = 1; i <= n; ++i){if (dfn[i] == -1){tarjan(i);}}int x;while (k--){scanf("%d",&x);int u = nd[x].u;int v = nd[x].v;int sum = ans;if (belong[u] == belong[v]){printf("%d\n",sum);}else{int tmp = num[belong[u]] + num[belong[v]];for (j = 1; j <= n; ++j) vt[j] = false;//这里表示该连通块是否已经加入for (i = 1; i <= n; ++i){if (belong[i] == belong[u] || belong[i] == belong[v]) continue;if (isok[u][i] && isok[i][v] && !vt[belong[i]]){vt[belong[i]] = true;tmp += num[belong[i]];}}sum = max(sum,tmp);printf("%d\n",sum);}}}return 0;
}

View Code

SDUT 2170 The Largest SCC bfs+tarjan相关推荐

  1. SDUT 2860-生日Party(BFS)

    生日Party Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描写叙述 Sherlock的生日即将来临,Sherlock打算邀请几个好 ...

  2. sdut 1028 Catch That Cow( BFS)

    http://www.cnblogs.com/shenben/p/5575387.html#top

  3. 复杂网络-标准公开数据集

    http://vlado.fmf.uni-lj.si/pub/networks/data/ SNAP(Stanford Large Network Dataset Collection)实验数据集 主 ...

  4. 算法竞赛——强连通分量

    强连通分量 强连通的定义是:有向图 G 强连通是指,G 中任意两个结点连通. 强连通分量(Strongly Connected Components,SCC)的定义是:极大的强连通子图也可以说,在强连 ...

  5. 记第一场cf比赛(Codeforces915)

    比赛感想 本来21:05开始的比赛,结果记成21:30了...晚了25分钟才开始[捂脸] 这次是Educational Round,所以还比较简单. 前两道题一眼看去模拟+贪心,怕错仔细看了好几遍题, ...

  6. PAT甲级1094 The Largest Generation:[C++题解]邻接表存树、每层节点数量、vector模拟bfs层序遍历、bfs另类实现

    文章目录 题目分析 题目链接 题目分析 来源:PAT网站 题意重述:求一棵树中结点数量最多的层数,并输出最大的数量. 分析:使用邻接矩阵存储树,bool型变量g[N][N] 邻接矩阵,如果有边 置为t ...

  7. 【BFS】【并查集】【Tarjan】【LCA】Gym - 101173H - Hangar Hurdles

    给你一张地图,给你q次询问,每次问你从A点到B点,最大能移动多大的箱子. 把每个点所能容纳的最大箱子求出来(BFS,八连通,一开始将所有边界点和障碍点入队).然后从大到小排序.然后用并查集将相邻(四联 ...

  8. 【UVA11324】The Largest Clique (SCC)

    题意: 给一张有向图G,求一个结点数最大的结点集,使得该结点中任意两个结点 u 和 v满足:要么 u 可以到达 v, 要么 v 可以到达 u(u 和 v 相互可达也可以). 分析: Tarjan求SC ...

  9. UVA11324-- The Largest Clique(SCC+DP)

    题目链接 题意:给出一张有向图,求一个结点数最大的结点集,使得该结点集中随意两个结点u和v满足:要么u能够到到v,要么v能够到达u(u和v能够互相到达) 思路:我们能够缩点,用Tarjan求出全部强连 ...

最新文章

  1. linux网络管理证书,计算机网络管理工程师技术水平证书有什么用
  2. 贴片铝电容识别及型号_贴片钽电容封装及规格和参数资料
  3. 前端学习(2998):vue+element今日头条管理--element引入
  4. 6大设计原则之单一职责原则
  5. 重温前端基础(二) 移动WEB开发
  6. leetCode 204. Count Primes 哈希 求素数
  7. mybatis查询返回null解决方案
  8. 如何判断一个类是无用的类?
  9. android手机慢,Android手机运行慢?!教你一秒“提速”50%
  10. UGUI的ScrollRect
  11. 算法:线性时间选择(C/C++)
  12. if条件句有大括号和没有大括号的区别
  13. 编写一个程序求解字谜游戏问题
  14. 致我爱的动漫--Fate 系列 Part 1:《Fate/Zero》
  15. Global and Local Enhancement Networks for Paired and Unpaired Image Enhancement
  16. Simulink三相电机仿真(4)
  17. 让你的 wowza 服务器提供 RESTful web 服务
  18. 基于Java Web的流浪猫狗救助网站
  19. python编程设计高级_Python编程高级技巧| 选择好的名称
  20. 解决npm构建报错:An unhandled exception occurred: ENOTEMPTY: directory not empty

热门文章

  1. 几款Linux系统漏洞扫描、评估工具简介
  2. 成功恢复新网LINUX REISERFS 6块盘 RAID5邮件服务器
  3. JavaScript中的this详解
  4. 组策略下发URL地址时的问题
  5. 大数据开发笔记(七):Kafka分布式流式处理
  6. 如何才能在大数据中获取价值
  7. 高度固定 宽度裁剪_六一童装系列:女童汉服连衣服裁剪图分享及缝制工艺解说...
  8. java 位运算 hashcode_hashcode面试题
  9. 连接设备不支持android,安卓手机不识别U盘、不能连接PC的处理方法
  10. HDU 5586 Sum (预处理 + 动态规划)