HDU3836 Tarjan缩点
2013-06-20 13:20
246 查看
/*
通过强连通分量Tarjan算法后,进行缩点,然后算强连通点的入度跟出度的分量数目即可。
答案即为入度为0或出度为0的点数目的最大值。 这点可以将缩点后图形堪称有向无环图,仿照树的定义,根为入度为0的点,叶子为出度为0的点。很明显的,要使其成为强连通图,令f为树根数,g为叶子数,则答案为max(f,g),特别的,当缩点只有一个点时,答案为0.
*/
通过强连通分量Tarjan算法后,进行缩点,然后算强连通点的入度跟出度的分量数目即可。
答案即为入度为0或出度为0的点数目的最大值。 这点可以将缩点后图形堪称有向无环图,仿照树的定义,根为入度为0的点,叶子为出度为0的点。很明显的,要使其成为强连通图,令f为树根数,g为叶子数,则答案为max(f,g),特别的,当缩点只有一个点时,答案为0.
*/
/* * @author ipqhjjybj * @date 20130620 */ #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <iostream> #include <cmath> #include <algorithm> #include <numeric> #include <utility> #include <cstring> #include <vector> #include <queue> #include <map> #include <stack> #include <string> #include <memory.h> using namespace std; #define inf 0x3f3f3f3f #define MAXN 30000 #define clr(x,k) memset((x),(k),sizeof(x)) #define cpy(x,k) memcpy((x),(k),sizeof(x)) #define Base 10000 #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) int n,m; struct node{ int to,next,from; }Edge[50050]; int head[50050]; int tot; int low[50050],temp[50050],dfn[50050]; stack<int> st; int scc_num,lay; void add(int a,int b){ Edge[tot].to = b; Edge[tot].from = a; Edge[tot].next = head[a]; head[a]=tot++; } //构图 void init(){ int a,b; tot = 0; clr(head,-1); for(int i = 0;i < m;i++){ scanf("%d %d",&a,&b); add(a,b); } } //Targan算法实现 int Targan(int k,int lay,int& scc_num){ int j; temp[k]=1; dfn[k]=low[k]=lay; st.push(k); for(int i=head[k];i != -1;i=Edge[i].next){ if(temp[Edge[i].to]==0){ Targan(Edge[i].to,++lay,scc_num); } if(temp[Edge[i].to]==1) low[k] = min(low[k],low[Edge[i].to]); } if(dfn[k]==low[k]){ ++scc_num; do{ j = st.top(); low[j]=scc_num; temp[j]=2; st.pop(); }while(j!=k); } return 0; } int in[MAXN],out[MAXN]; //缩点 void degreeSet(){ clr(in,0),clr(out,0); for(int i = 0;i < tot;i++){ if(low[Edge[i].to]!=low[Edge[i].from]){ //缩点操作 out[low[Edge[i].to]]++; in[low[Edge[i].from]]++; } } } int main(){ while(scanf("%d %d",&n,&m)!=EOF){ init(); clr(low,0); clr(temp,0); scc_num=0,lay=1; st.empty(); for(int i = 1;i<=n;i++){ if(temp[i]==0) Targan(i,lay,scc_num); } degreeSet(); int inNum,outNum; inNum = outNum=0; for(int i=1;i <= scc_num;i++){ if(!in[i]) inNum++; if(!out[i]) outNum++; } if(scc_num==1){ printf("0\n"); }else printf("%d\n",max(inNum,outNum)); } return 0; }
相关文章推荐
- POJ 1236 Tarjan缩点及思维..
- POJ 2553 Tarjan缩点+判断出度为0
- 1827 tarjan+缩点
- POJ 1236 Network of Schools(强连通 Tarjan+缩点)
- HDU 1827 Summer Holiday(Tarjan缩点)
- [BZOJ 1051][HAOI 2006]受欢迎的牛(tarjan缩点)
- POJ 3352--Road Construction【无向图增加最少的边成为边双连通图 && tarjan求ebc && 缩点构造缩点树】
- hdu1827 Summer Holiday(tarjan+ 缩点)
- BZOJ 1924 [Sdoi2010]所驼门王的宝藏 tarjan缩点+拓扑DP
- POJ2186(Tarjan缩点)
- POJ 3177&&3352题解 tarjan算割边 求双连通分量 缩点
- NOIP2009最优贸易[spfa变形|tarjan 缩点 DP]
- 【hdu 3861】The King’s Problem(Tarjan缩点+匈牙利算法)
- POJ-1236(tarjan缩点)
- bzoj 2427 HAOI 2010 软件安装 (dp+tarjan缩点)
- hdu 3861(tarjan 缩点 + 二分图匹配 求最小路径覆盖
- [笔记]关于tarjan求连通分量 & 缩点
- Tarjan缩点+SPFA——缩点
- 【bzoj2427】【软件安装】tarjan缩点+树形依赖背包
- 2017NOIP模拟赛 软件安装(tarjan缩点+树形dp)