SDUT 2170 The Largest SCC bfs+tarjan
题意:
给你一个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相关推荐
- SDUT 2860-生日Party(BFS)
生日Party Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描写叙述 Sherlock的生日即将来临,Sherlock打算邀请几个好 ...
- sdut 1028 Catch That Cow( BFS)
http://www.cnblogs.com/shenben/p/5575387.html#top
- 复杂网络-标准公开数据集
http://vlado.fmf.uni-lj.si/pub/networks/data/ SNAP(Stanford Large Network Dataset Collection)实验数据集 主 ...
- 算法竞赛——强连通分量
强连通分量 强连通的定义是:有向图 G 强连通是指,G 中任意两个结点连通. 强连通分量(Strongly Connected Components,SCC)的定义是:极大的强连通子图也可以说,在强连 ...
- 记第一场cf比赛(Codeforces915)
比赛感想 本来21:05开始的比赛,结果记成21:30了...晚了25分钟才开始[捂脸] 这次是Educational Round,所以还比较简单. 前两道题一眼看去模拟+贪心,怕错仔细看了好几遍题, ...
- PAT甲级1094 The Largest Generation:[C++题解]邻接表存树、每层节点数量、vector模拟bfs层序遍历、bfs另类实现
文章目录 题目分析 题目链接 题目分析 来源:PAT网站 题意重述:求一棵树中结点数量最多的层数,并输出最大的数量. 分析:使用邻接矩阵存储树,bool型变量g[N][N] 邻接矩阵,如果有边 置为t ...
- 【BFS】【并查集】【Tarjan】【LCA】Gym - 101173H - Hangar Hurdles
给你一张地图,给你q次询问,每次问你从A点到B点,最大能移动多大的箱子. 把每个点所能容纳的最大箱子求出来(BFS,八连通,一开始将所有边界点和障碍点入队).然后从大到小排序.然后用并查集将相邻(四联 ...
- 【UVA11324】The Largest Clique (SCC)
题意: 给一张有向图G,求一个结点数最大的结点集,使得该结点中任意两个结点 u 和 v满足:要么 u 可以到达 v, 要么 v 可以到达 u(u 和 v 相互可达也可以). 分析: Tarjan求SC ...
- UVA11324-- The Largest Clique(SCC+DP)
题目链接 题意:给出一张有向图,求一个结点数最大的结点集,使得该结点集中随意两个结点u和v满足:要么u能够到到v,要么v能够到达u(u和v能够互相到达) 思路:我们能够缩点,用Tarjan求出全部强连 ...
最新文章
- linux网络管理证书,计算机网络管理工程师技术水平证书有什么用
- 贴片铝电容识别及型号_贴片钽电容封装及规格和参数资料
- 前端学习(2998):vue+element今日头条管理--element引入
- 6大设计原则之单一职责原则
- 重温前端基础(二) 移动WEB开发
- leetCode 204. Count Primes 哈希 求素数
- mybatis查询返回null解决方案
- 如何判断一个类是无用的类?
- android手机慢,Android手机运行慢?!教你一秒“提速”50%
- UGUI的ScrollRect
- 算法:线性时间选择(C/C++)
- if条件句有大括号和没有大括号的区别
- 编写一个程序求解字谜游戏问题
- 致我爱的动漫--Fate 系列 Part 1:《Fate/Zero》
- Global and Local Enhancement Networks for Paired and Unpaired Image Enhancement
- Simulink三相电机仿真(4)
- 让你的 wowza 服务器提供 RESTful web 服务
- 基于Java Web的流浪猫狗救助网站
- python编程设计高级_Python编程高级技巧| 选择好的名称
- 解决npm构建报错:An unhandled exception occurred: ENOTEMPTY: directory not empty
热门文章
- 几款Linux系统漏洞扫描、评估工具简介
- 成功恢复新网LINUX REISERFS 6块盘 RAID5邮件服务器
- JavaScript中的this详解
- 组策略下发URL地址时的问题
- 大数据开发笔记(七):Kafka分布式流式处理
- 如何才能在大数据中获取价值
- 高度固定 宽度裁剪_六一童装系列:女童汉服连衣服裁剪图分享及缝制工艺解说...
- java 位运算 hashcode_hashcode面试题
- 连接设备不支持android,安卓手机不识别U盘、不能连接PC的处理方法
- HDU 5586 Sum (预处理 + 动态规划)