poj1236Network of Schools Tarjan裸题

其实就是手打了个Tarjan的模板

输出的时候注意是入度为0的点的个数和max(入度0的个数,出度0的个数),在n=1时特判为0即可

——以后图论要渐渐模板化,方便使用

  1 #include <cstdio>
  2 #include <iostream>
  3 using namespace std;
  4 struct E
  5 {
  6     int from,to,next;
  7 } e[100001];
  8 int Enum=0,sttop=0;
  9 int first[101];
 10 int dfn[101],low[101];
 11 bool que[101];
 12 int tar[101];
 13 int sum,n,_ans,ans;
 14 int df;
 15 int num[101];
 16 int st[101];
 17 void add(int from,int to)
 18 {
 19     E New;
 20     New.from=from;
 21     New.to=to;
 22     New.next=first[from];
 23     e[++Enum]=New;
 24     first[from]=Enum;
 25 }
 26 void tarjan_dfs(int u)
 27 {
 28     st[++sttop]=u;
 29     int v;
 30     que[u]=1;
 31     dfn[u]=low[u]=++df;
 32     for(int i=first[u];i;i=e[i].next)
 33     {
 34         v=e[i].to;
 35         if(dfn[v]==0)
 36         {
 37             tarjan_dfs(v);
 38             low[u]=min(low[u],low[v]);
 39         }
 40         else
 41         if(que[v])
 42             low[u]=min(low[u],dfn[v]);
 43     }
 44     if(dfn[u]==low[u])
 45     {
 46         sum++;
 47         do
 48         {
 49             v=st[sttop--];
 50             que[v]=0;
 51             tar[v]=sum;
 52         }while(u!=v);
 53     }
 54 }
 55 int tarjan()
 56 {
 57     sum=0;df=0;sttop=0;
 58     for(int i=1;i<=n;i++)
 59         if(!dfn[i])
 60             tarjan_dfs(i);
 61     for(int i=1;i<=n;i++)
 62         first[i]=0;//清空原有边
 63     for(int i=1;i<=Enum;i++)
 64     if(tar[e[i].from]!=tar[e[i].to])
 65     {
 66         e[i].from=tar[e[i].from];
 67         e[i].to=tar[e[i].to];
 68         e[i].next=first[e[i].from];
 69         first[e[i].from]=i;
 70         num[e[i].to]++;
 71     }
 72     return sum;
 73 }
 74 void dfs(int k)
 75 {
 76     if(first[k])
 77         for(int i=first[k];i;i=e[i].next)
 78             dfs(e[i].to);
 79     else
 80     if(!que[k])
 81     {
 82         _ans++;
 83         que[k]=1;
 84     }
 85 }
 86 int main()
 87 {
 88     scanf("%d",&n);
 89     for(int i=1;i<=n;i++)
 90     {
 91         int k;
 92         scanf("%d",&k);
 93         while(k>0)
 94         {
 95             add(i,k);
 96             scanf("%d",&k);
 97         }
 98     }
 99     n=tarjan();
100     for(int i=1;i<=n;i++)
101         que[i]=0;
102     for(int i=1;i<=n;i++)
103     if(!num[i])
104     {
105         ans++;
106         dfs(i);
107     }
108     printf("%d\n%d\n",ans,n==1?0:max(ans,_ans));
109     return 0;
110 }
时间: 2024-10-27 05:04:12

poj1236Network of Schools Tarjan裸题的相关文章

POJ1236-Network of Schools(Tarjan + 缩点)

主题链接 题意:给定一张有向图,问最少选择几个点能遍历全图.以及最少加入几条边使得有向图成为一个强连通图. 思路:对于有向图而言,首先求出有几个强连通分量,之后将每一个强连通分量缩点,形成DAG.本题开头第一句就说图是连通的了. 之后想要遍历整张图的话.仅仅要找出入度为0的点有几个,而加入边的数量就取决于全部点的出入度大小. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <

POJ1236Network of Schools[tarjan 缩点]

Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16571   Accepted: 6558 Description A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a li

tarjan讲解(用codevs1332(tarjan的裸题)讲解)

主要借助这道比较裸的题来讲一下tarjan这种算法 tarjan是一种求解有向图强连通分量的线性时间的算法.(用dfs来实现) 如果两个顶点可以相互通达,则称两个顶点强连通.如果有向图G的每两个顶点都强连通,称G是一个强连通图.有向图的极大强连通子图,称为强连通分量. 在上面这张有向图中1,2,3,4形成了一个强连通分量,而1,2,4,和1,3,4并不是(因为它们并不是极大强连通子图). tarjan是用dfs来实现的(用了tarjan后我们就可以对图进行缩点(当然这道裸题用不到)) 这道题只要

【POJ3352】Road Construction tarjan求边-双连通分量,裸题模板题

转载请注明出处:http://blog.csdn.net/vmurder/article/details/42671851 其实我就是觉得原创的访问量比未授权盗版多有点不爽233... 裸题只给模板. tarjan可以实现. 太水不发题解. 代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 1010 #define M 202

ZOJ 2588 Burning Bridges 求无向图桥 边双连通裸题

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1588 binshen的板子: #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #i

SZOJ 167 Lca裸题

一道.......一道我改了一周的裸题 无根树建双向边 无根树建双向边 无根树建双向边 重要的事情说三遍(微笑) 还有要开longlong 还有双向边不是双倍边(微笑) 我真是,能把自己气吐血10次就不把自己气吐血9次 [问题描述] 已知一棵nn个点的树,点从1开始标号,树上每条边都有一个正整数边权. 有qq个询问,每个询问由type,u,vtype,u,v三个正整数构成. 当type=1type=1时,询问uu到vv路径上所有边权的二进制异或和. 当type=2type=2时,询问uu到vv路

hdu1159 poj1458 LCS裸题

HDU 1159 题意:找LCS 思路:裸题 n*m的写法,我的写法好像比较奇怪...用一个ci保存s2第i位可以做为s1的公共子序列的最大值,s1的每一位遍历s2,遍历的时候记录前面出现过的ci的最大值,ci一定是一个连序的上升序列,我的好像不是正经的LCS的算法,改天还是要学习一个的 AC代码: #include "iostream" #include "string.h" #include "stack" #include "qu

HDU 4893 线段树裸题

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2512    Accepted Submission(s): 751 Problem Description Recently, Doge got a funny birthday present from his new friend, Pro

POJ 3624 Charm Bracelet(01背包裸题)

Charm Bracelet Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 38909   Accepted: 16862 Description Bessie has gone to the mall's jewelry store and spies a charm bracelet. Of course, she'd like to fill it with the best charms possible fro