[HDOJ4635]Strongly connected(强连通分量,缩点)
2016-05-24 14:55
435 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4635
题意:给一张图,问最多往这张图上加多少条边,使这张图仍然无法成为一个强连通图。
起初是先分析样例可以知道,一个强连通分量里应当加边加至一个完全图,这样对整个图的连通贡献是没有的。然后把每个强连通分量里的边数扩展至num-out-1,但是发现连通分量之间的关系不好处理,所以反着做。
考虑一张有向完全图的边数为n*(n-1),再去掉现在已经有的边数m,那么不考虑无法成为强连通图这一要求,我们还可以加n*(n-1)-m条边。现在问题变成了最少去掉多少条边,这个图不是一个强连通图。
我们不希望浪费任何一个强连通分量,所以我们最终的情况应当是有一个强连通分量是无法到达其他强连通分量,并且其他强连通分量早已连接成一整个强连通分量。要保证这种边尽量多,也就是保证排除的点尽可能少,我们枚举其中的一个强连通分量(因为单个分量的点数一定小于多个连通分量点数相加后的最小值)。接下来在图上找入度或者出度为0的连通分量,从这种分量出或者入是不会影响连通性的,所以得解。
题意:给一张图,问最多往这张图上加多少条边,使这张图仍然无法成为一个强连通图。
起初是先分析样例可以知道,一个强连通分量里应当加边加至一个完全图,这样对整个图的连通贡献是没有的。然后把每个强连通分量里的边数扩展至num-out-1,但是发现连通分量之间的关系不好处理,所以反着做。
考虑一张有向完全图的边数为n*(n-1),再去掉现在已经有的边数m,那么不考虑无法成为强连通图这一要求,我们还可以加n*(n-1)-m条边。现在问题变成了最少去掉多少条边,这个图不是一个强连通图。
我们不希望浪费任何一个强连通分量,所以我们最终的情况应当是有一个强连通分量是无法到达其他强连通分量,并且其他强连通分量早已连接成一整个强连通分量。要保证这种边尽量多,也就是保证排除的点尽可能少,我们枚举其中的一个强连通分量(因为单个分量的点数一定小于多个连通分量点数相加后的最小值)。接下来在图上找入度或者出度为0的连通分量,从这种分量出或者入是不会影响连通性的,所以得解。
/* ━━━━━┒ギリギリ♂ eye! ┓┏┓┏┓┃キリキリ♂ mind! ┛┗┛┗┛┃\○/ ┓┏┓┏┓┃ / ┛┗┛┗┛┃ノ) ┓┏┓┏┓┃ ┛┗┛┗┛┃ ┓┏┓┏┓┃ ┛┗┛┗┛┃ ┓┏┓┏┓┃ ┛┗┛┗┛┃ ┓┏┓┏┓┃ ┃┃┃┃┃┃ ┻┻┻┻┻┻ */ #include <algorithm> #include <iostream> #include <iomanip> #include <cstring> #include <climits> #include <complex> #include <fstream> #include <cassert> #include <cstdio> #include <bitset> #include <vector> #include <deque> #include <queue> #include <stack> #include <ctime> #include <set> #include <map> #include <cmath> using namespace std; #define fr first #define sc second #define cl clear #define BUG puts("here!!!") #define W(a) while(a--) #define pb(a) push_back(a) #define Rint(a) scanf("%d", &a) #define Rll(a) scanf("%lld", &a) #define Rs(a) scanf("%s", a) #define Cin(a) cin >> a #define FRead() freopen("in", "r", stdin) #define FWrite() freopen("out", "w", stdout) #define Rep(i, len) for(int i = 0; i < (len); i++) #define For(i, a, len) for(int i = (a); i < (len); i++) #define Cls(a) memset((a), 0, sizeof(a)) #define Clr(a, x) memset((a), (x), sizeof(a)) #define Full(a) memset((a), 0x7f7f, sizeof(a)) #define lp p << 1 #define rp p << 1 | 1 #define pi 3.14159265359 #define RT return typedef long long LL; typedef long double LD; typedef unsigned long long ULL; typedef pair<int, int> pii; typedef pair<string, int> psi; typedef map<string, int> msi; typedef vector<int> vi; typedef vector<LL> vl; typedef vector<vl> vvl; typedef vector<bool> vb; typedef struct Edge { int u; int v; int next; Edge() { next = -1; } }Edge; const int maxn = 100100; const int maxm = 100100; int n, m; int head[maxn], ecnt; Edge edge[maxm]; int bcnt, dindex; int dfn[maxn], low[maxn]; int stk[maxn], top; int belong[maxn], num[maxn]; int in[maxn], out[maxn]; bool instk[maxn]; void init() { Clr(head, -1); Cls(edge); Cls(instk); Cls(dfn); Cls(low); Cls(num); Cls(belong); Cls(in); Cls(out); ecnt = top = bcnt = dindex = 0; } void adde(int uu, int vv) { edge[ecnt].u = uu; edge[ecnt].v = vv; edge[ecnt].next = head[uu]; head[uu] = ecnt++; } void tarjan(int u) { int v = u; dfn[u] = low[u] = ++dindex; stk[++top] = u; instk[u] = 1; for(int i = head[u]; ~i; i=edge[i].next) { v = edge[i].v; if(!dfn[v]) { tarjan(v); low[u] = min(low[u], low[v]); } else if(instk[v]) low[u] = min(low[u], dfn[v]); } if(dfn[u] == low[u]) { bcnt++; do { v = stk[top--]; instk[v] = 0; belong[v] = bcnt; } while(v != u); } } int main() { // FRead(); int T, _ = 1, u, v; Rint(T); W(T) { printf("Case %d: ", _++); init(); Rint(n); Rint(m); Rep(i, m) { Rint(u); Rint(v); adde(u, v); } For(i, 1, n+1) if(!dfn[i]) tarjan(i); if(bcnt == 1) { printf("-1\n"); continue; } For(u, 1, n+1) { num[belong[u]]++; for(int i = head[u]; ~i; i=edge[i].next) { int v = edge[i].v; if(belong[u] != belong[v]) { in[belong[v]]++; out[belong[u]]++; } } } int sum = n*(n-1)-m; int ret = 0; For(i, 1, bcnt+1) { if(in[i] == 0 || out[i] == 0) { ret = max(ret, sum-num[i]*(n-num[i])); } } printf("%d\n", ret); } RT 0; }
相关文章推荐
- 编程小练习
- 使用OBS+Azure Media Service+CDN进行直播,配置方法及最佳实践
- Maven 部署webapp 到远程服务器
- 让IE浏览器支持HTML5标准的方法
- PHP如何开发 MVC框架(一)
- [Java并发包学习九]Java中的阻塞队列
- 如何在QT的label上显示图像
- Android高级UI GridView
- C# dll生成和调用
- [Java并发包学习八]深度剖析ConcurrentHashMap
- LeetCode 118. Pascal's Triangle
- 正则表达式限制input的输入值
- LTE 协议栈 学习
- Linux的Docker上如何安装MySQL
- hibernate get/load方法区别
- 七牛EVM云主机搭建mycollab
- 错误异常整理
- 228. Summary Ranges
- 弹窗:popwindow 4部分
- 深入浅出JMS(一)--JMS基本概念