Codeforces Round #286 div.2 D 505D. Mr. Kitayuta's Technology【强连通分量,弱联通分量】
来源:互联网 发布:沙河网络服装批发市场 编辑:程序博客网 时间:2024/06/05 19:44
题目链接:http://codeforces.com/contest/505/problem/D
题目大意:
在一个图中,有n个顶点,给出m对数字(u,v)表示顶点u和顶点v必须直接或者间接相连,让你构造一个这样的图,输出最少需要多少条边。
分析:
毫无疑问,n个顶点的话,我们最多可以用n条边,使得n个顶点构成一个环,满足所有的情况(任意两点都是联通的),但是这并不一定是最少的边。
于是我们还需要找一个方法确定最少需要多少条边。
首先我们利用题目给出的点对建图,得到图G。对于G中的弱联通分量来说,分两种情况讨论:
1.这个弱联通分量中没有环。那么我们能够利用拓扑排序将这个图变成一条链子,假设这个分量中有n1个顶点,那么毫无疑问,所需要的边数为n1-1。
2.这个弱联通分量中有环。假设这个分量中有n2个顶点,那么我们可以用n2条边,将这个n2个顶点构成一个环,
有了上述分析,那么我们现在的工作就是需要判断每个弱联通分量里面有没有环即可。判断环的方法呢,那就是检测这个点所在的强连通分量里点的个数是否等于1,如果大于1,那么说明这个分量中有环,如果等于1,那么说明这个分量中没有环。
#include<map>#include<set>#include<cmath>#include<ctime>#include<stack>#include<queue>#include<cstdio>#include<cctype>#include<string>#include<vector>#include<cstring>#include<iomanip>#include<iostream>#include<algorithm>#include<functional>#define fuck(x) cout<<"["<<x<<"]"#define FIN freopen("input.txt","r",stdin)#define FOUT freopen("output.txt","w+",stdout)using namespace std;typedef long long LL;typedef pair<int, int>PII;const int MX = 2e5 + 5;const int INF = 0x3f3f3f3f;struct Edge { int v, nxt, sign;} E[MX];int Head[MX], rear;void edge_init() { rear = 0; memset(Head, -1, sizeof(Head));}void edge_add(int u, int v, int s) { E[rear].v = v; E[rear].nxt = Head[u]; E[rear].sign = s; Head[u] = rear++;}int n, m;int A[MX], cnt[MX], cir[MX], vis[MX], siz;int DFS1(int u, int id) { A[u] = -1; int ret = 1; for(int i = Head[u]; ~i; i = E[i].nxt) { int v = E[i].v; if(!A[v]) ret += DFS1(v, id); } A[u] = id; return ret;}bool DFS2(int u) { vis[u] = -1; bool ret = false; for(int i = Head[u]; ~i; i = E[i].nxt) { int v = E[i].v; if(E[i].sign) { if(vis[v] == -1) { ret = true; break; } if(!vis[v] && DFS2(v)) { ret = true; break; } } } vis[u] = 1; return ret;}int solve() { siz = 0; memset(A, 0, sizeof(A)); memset(cir, 0, sizeof(cir)); memset(cnt, 0, sizeof(cnt)); memset(vis, 0, sizeof(vis)); for(int i = 1; i <= n; i++) { if(!A[i]) siz++, cnt[siz] = DFS1(i, siz); if(!vis[i] && DFS2(i)) cir[A[i]] = 1; } int ans = 0; for(int i = 1; i <= siz; i++) { if(cir[i]) ans += cnt[i]; else ans += cnt[i] - 1; } return ans;}int main() { edge_init(); //FIN; scanf("%d%d", &n, &m); for(int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); edge_add(u, v, 1); edge_add(v, u, 0); } printf("%d\n", solve()); return 0;}
阅读全文
0 0
- Codeforces Round #286 div.2 D 505D. Mr. Kitayuta's Technology【强连通分量,弱联通分量】
- Codeforces Round #286 div.2 D 505D. Mr. Kitayuta's Technology【强连通分量,弱联通分量】
- Codeforces Round #286 (Div. 2) D. Mr. Kitayuta's Technology 强连通分量 有向图求环
- Codeforces Round #286 (Div. 1) B. Mr. Kitayuta's Technology (强连通分量)
- Codeforces Round #286 (Div. 2) D.Mr. Kitayuta's Technology
- Codeforces Round #286 (Div. 1) B. Mr. Kitayuta's Technology 连通分量 拓扑排序
- Codeforce 505D - Mr. Kitayuta's Technology 弱联通分量+拓扑排序
- codeforces 505 D Mr. Kitayuta's Technology
- Codeforces Round #347 (Div. 2) D. Graph Coloring(强联通分量缩点+2-SAT)
- [Codeforces Round #369 (Div. 2)D. Directed Roads]Tarjan强连通分量+组合计数
- cf 505d Mr. Kitayuta's Technology
- 有向图强连通分量Tarjan算法+ Codeforces Round #267 (Div. 2) D.Fedor and Essay
- Codeforces Round #286 (Div. 1) D. Mr. Kitayuta's Colorful Graph (并查集 STL)
- Codeforces Round #286 div.1 D 506D D. Mr. Kitayuta's Colorful Graph【并查集】
- [Codeforces Round #286 DIV1B (CF506B)] Mr. Kitayuta's Technology
- Codeforces Round #286 (Div. 2)-A. Mr. Kitayuta's Gift
- Codeforces Round #286 (Div. 2) A. Mr. Kitayuta's Gift
- Codeforces Round #286 (Div. 1) D. Mr. Kitayuta's Colorful Graph 高维并查集,STL连招
- nodejs 5 nodejs的web应用-http服务器(http, 路由,get,post,https)
- View inflate 方法与 LayoutInflater inflate 方法的区别详解
- 抽象工厂模式
- SpringMVC
- 关于 quartz 1.6.1 的一个死等问题,导致任务不执行
- Codeforces Round #286 div.2 D 505D. Mr. Kitayuta's Technology【强连通分量,弱联通分量】
- Linux命令之awk
- 使用Axis2生成soap客户端
- get_maincat()分类调用方法
- Nginx服务器安装,高性能的HTTP、TCP、反向代理、负载均衡等服务和配置
- 文章标题
- SWAT—Samba WEB管理工具
- 使用XDP(eXpress Data Path)防御DDoS攻击
- linux配置网络