【强连通 && 最多可以加几条边使得图不为强连通图】HDU
来源:互联网 发布:冒险岛伴侣官方域名 编辑:程序博客网 时间:2024/05/02 01:52
Problem Description
输入T组测试数据,每组测试数据输入n,m分别代表n个点,m条边。
接下来m行,每行u,v代表u->v有一条单向边,问你最多可以加多少条边,图不能是强连通图。
思路:
要使得图不为强连通图,那么至少得有两个缩点,这题核心就在于,将图如何分成两个缩点,使得边最多。一开始,我的思路,将图缩点,然后找到点最少的缩点。令它为一个缩点(由Min个点构成),其他的点为另外一个缩点(由t个点构成也就是n-Min)。那么总共有的边就是t * (t - 1) + Min * (Min - 1) + t * Min,就是两个缩点各自的完全图 + 一个缩点到另一个缩点的所有边。在减m就是结果,提交Wrong了。发现没有考虑最少的缩点的度的情况,如果出度,入度都不为0,那么其他点构成强连通后,整个图就变成强连通图了,所以得找出度或者入度为0的缩点,并且所含的点最少。然后我就思考这样一定成立吗。后面手写了一些情况发现都是成立的,后面改了提交就AC了。
#include<bits/stdc++.h>using namespace std;#define mm 100055#define inf 0x3f3f3f3fstruct node{ int u, to, next;};node Map[mm * 2];int head[mm], vis[mm], dfn[mm], low[mm], Stack[mm], top, sig, N, n;//vis[i]代表i这个点属于vis[i]这个强连通分量里int d[mm], c[mm], r[mm];void add(int u, int v, int &cnt)//前向星{ Map[cnt].u = u; Map[cnt].to = v; Map[cnt].next = head[u]; head[u] = cnt++;}void tardfs(int u)//强连通分量 缩点{ low[u] = dfn[u] = sig++; Stack[top++] = u; for(int i = head[u]; ~i; i = Map[i].next) { int to = Map[i].to; if(!dfn[to]) { tardfs(to); low[u] = min(low[u], low[to]); } else if(!vis[to]) { low[u] = min(low[u], dfn[to]); } } if(low[u] == dfn[u]) { N++; do { int t = Stack[top - 1]; vis[t] = N; top--; }while(Stack[top] != u); }}void tarjan(){ top = 0, sig = 1, N = 0; memset(dfn, 0, sizeof(dfn)); memset(vis, 0, sizeof(vis)); for(int i = 1; i <= n; i++) { if(!vis[i]) tardfs(i); }}int main(){ int T, m, u, v, cas = 1, i; scanf("%d", &T); while(T--) { scanf("%d %d", &n, &m); int cnt = 0; memset(head, -1, sizeof(head)); for(i = 0; i < m; i++) { scanf("%d %d", &u, &v); add(u, v, cnt); } tarjan();//强连通分量 缩点 printf("Case %d: ", cas++); if(N == 1) printf("-1\n");//已经为强连通图 else { memset(d, 0, sizeof(d)); memset(c, 0, sizeof(c)); memset(r, 0, sizeof(r)); for(i = 0; i < cnt; i++)//缩点后的点的入度,出度是多少 { u = Map[i].u, v = Map[i].to; if(vis[u] != vis[v]) { c[vis[u]]++; r[vis[v]]++; } } for(i = 1; i <= n; i++) { d[vis[i]]++;//vis[i]里面有几个点 } long long Min = inf; for(i = 1; i <= N; i++)//找到入度或者出度为0的缩点,里面点最少的点 { if(Min > d[i]) { if(!c[i] || !r[i]) Min = d[i]; } } long long t = n - Min; printf("%lld\n", t * (t - 1) + Min * (Min - 1) + t * Min - m);//输出 } } return 0;}
阅读全文
0 0
- 【强连通 && 最多可以加几条边使得图不为强连通图】HDU
- 强连通图
- 强连通子图
- 判断强连通图
- 图-强连通模板
- hdu 1269 (强连通基础图)
- hdu 1269 强连通图的判定
- hdu 1269 强连通图的判定
- hdu 1269 强连通
- hdu 3594 (强连通)
- 连通图的强连通分支
- POJ-1236(有向图强连通分量 + 缩点 + 加边使得整个图强连通)
- HDU 1269 迷宫城堡(强连通分量):强连通图判定
- poj 1904 强连通图
- 强连通图的算法
- 强连通图的算法
- 强连通图的算法
- 强连通图的算法
- 1.1多媒体技术概述
- Linux ls命令详解
- 安卓编译的时候依赖包解析不了,老是下载不下来。Faled to resolve: com.squareup.retrofit2:converter-gson:2.3.0
- HDU-敌兵布阵
- 实际用户id(real user id)、有效用户id(effective user id)和保存的设置用户id(saved set-user-id)
- 【强连通 && 最多可以加几条边使得图不为强连通图】HDU
- 第三周 --顺序表 的基本运算
- 译-设计模式-结构模式之Adapter
- 51单片机实验(LED and KEY)
- gensim:bin转txt
- Buildings
- 截取URL参数
- 用python实现将数组元素按从小到大的顺序排列
- 机器学习相关材料和网站