HDOJ 2767 Proving Equivalences
来源:互联网 发布:1100网络键盘 编辑:程序博客网 时间:2024/05/20 22:29
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2767
题意:给你一个些点的关系,然后问你还需要加多少条边可以使这个图变成强连通,也就是每个点都可以通过其他的点到达另外的点。
如果这个图它不含环的话,很容易想到统计每个点的入度和出度,然后其中最大的那个就是我们要加的边的条数,但是实际情况肯定不可能是这样的,难免会遇到含环的情况。这里我们就可以考虑用Tarjan算法对图进行缩点,因为如果一个强连通分量中的每个点都可以通过其他点到达另外的点,所以我们只需要考虑这个强连通分量整个和其他点的关系,而不需要考虑内部的关系,所以我们就把一个强连通分量缩为一个点。
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int VM=20010;const int EM=50010;const int INF=0x3f3f3f3f;struct Edge{ int to,nxt;}edge[EM<<1];int n,m,cnt,head[VM];int dep,top,num;int dfn[VM],low[VM],vis[VM],stack[VM],belong[VM],indeg[VM],outdeg[VM];void addedge(int cu,int cv){ edge[cnt].to=cv;edge[cnt].nxt=head[cu];head[cu]=cnt++;}void Tarjan(int u){ dfn[u]=low[u]=++dep; stack[top++]=u; vis[u]=1; for(int i=head[u];i!=-1;i=edge[i].nxt){ int v=edge[i].to; if(!dfn[v]){ Tarjan(v); low[u] = min(low[u],low[v]); }else if(vis[v]) low[u] = min(low[u],dfn[v]); } int v; if(dfn[u]==low[u]){ num++; do{ v = stack[--top]; belong[v] = num; vis[v] = 0; }while(u != v); }}void init(){ cnt=0; memset(head,-1,sizeof(head)); dep = top = num = 0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(vis,0,sizeof(vis)); memset(belong,0,sizeof(belong)); memset(indeg,0,sizeof(indeg)); memset(outdeg,0,sizeof(outdeg));}int main(){ int t; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); if(n==1){ printf("0\n"); continue; } if(m==0){ printf("%d\n",n); continue; } init(); int u,v; while(m--){ scanf("%d%d",&u,&v); addedge(u,v); } for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i); if(num == 1){ printf("0\n"); continue; } for(int u=1;u<=n;u++) for(int i=head[u];i!=-1;i=edge[i].nxt){ int v=edge[i].to; if(belong[u]!=belong[v]){ outdeg[belong[u]]++; indeg[belong[v]]++; } } int ans1=0,ans2=0; for(int i=1; i<=num; i++){ if(indeg[i]==0) ans1++; if(outdeg[i]==0) ans2++; } printf("%d\n",max(ans1,ans2)); } return 0;}
1 0
- HDOJ--2767--Proving Equivalences
- HDOJ 2767 Proving Equivalences
- HDOJ 2767 Proving Equivalences
- hdoj 2767 Proving Equivalences【强连通&&tarjan】
- HDU 2767 Proving Equivalences
- HDU 2767 Proving Equivalences
- hdu 2767 Proving Equivalences
- HDU 2767 Proving Equivalences
- HDU 2767 Proving Equivalences
- hdu 2767 Proving Equivalences
- HDU 2767 Proving Equivalences
- HDU 2767 Proving Equivalences
- hdu 2767 Proving Equivalences
- HDU 2767 Proving Equivalences
- hdu 2767 Proving Equivalences
- LA-4287 & HDOJ-2767 Proving Equivalences 解题报告
- hdoj--2767--Proving Equivalences (scc+缩点)
- Proving Equivalences
- Apache Spark学习(二)
- css3-新增的选择器
- Android View事件派发机制详解与源码分析
- 将字符串循环左移N个位置(讯飞笔试题)
- 图的表示
- HDOJ 2767 Proving Equivalences
- Android 多线程-----AsyncTask详解
- Java并发编程:线程池的使用
- 自己挖的坑自己填之编译c文件与c++文件
- OC中的id类型
- mysql的limit经典用法及优化
- LeetCode 328 -Odd Even Linked List ( JAVA )
- 百度API经纬度和地址互相查询
- android序列化笔记