【tarjan】BZOJ 1051:受欢迎的牛
2015-12-30 10:01
351 查看
1051: [HAOI2006]受欢迎的牛
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3134 Solved: 1642
[Submit][Status][Discuss]
Description
每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头牛被所有的牛认为是受欢迎的。Input
第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B)Output
一个数,即有多少头牛被所有的牛认为是受欢迎的。Sample Input
3 31 2
2 1
2 3
Sample Output
1HINT
100%的数据N<=10000,M<=50000很久之前做过的一道题目。。
具体就是先tarjan缩点,点的权值就是这个连通分量的点的数量
然后找入度为0的点
只有一个就输出它的权值
多个就输0
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 6 #define maxn 10001 7 8 using namespace std; 9 10 inline int In() 11 { 12 int x=0;char ch=getchar(); 13 while(ch<'0'||ch>'9')ch=getchar(); 14 while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); 15 return x; 16 } 17 18 struct ed{ 19 int u,v; 20 }edge[maxn*5]; 21 22 struct node{ 23 int to,last; 24 }e[maxn*10]; 25 26 int last[maxn],tot=0,dfn[maxn],low[maxn],father[maxn],sta[maxn],top=0,cnt=0,size=0,num[maxn],in[maxn]; 27 28 bool ins[maxn]; 29 30 void add(int u,int v){e[++tot].to=v,e[tot].last=last[u],last[u]=tot;} 31 32 void tarjan(int poi) 33 { 34 dfn[poi]=low[poi]=++cnt; 35 ins[poi]=1;sta[++top]=poi; 36 for(int i=last[poi];i;i=e[i].last) 37 { 38 int u=e[i].to; 39 if(!dfn[u]) 40 { 41 tarjan(u); 42 low[poi]=min(low[u],low[poi]); 43 } 44 else if(ins[u]) low[poi]=min(low[poi],dfn[u]); 45 } 46 if(dfn[poi]==low[poi]) 47 { 48 size++; 49 int vv; 50 do{ 51 vv=sta[top]; 52 father[vv]=size; 53 ins[vv]=0; 54 num[size]++; 55 top--; 56 }while(vv!=poi); 57 } 58 } 59 60 int main() 61 { 62 freopen("1051.in","r",stdin); 63 int n,m,str=0; 64 n=In(),m=In(); 65 for(int i=1;i<=n;i++)father[i]=i; 66 for(int i=1;i<=m;i++) 67 edge[i].u=In(),edge[i].v=In(),add(edge[i].u,edge[i].v); 68 for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i); 69 memset(last,0,sizeof(last)); 70 tot=0; 71 for(int i=1;i<=m;i++)if(father[edge[i].u]!=father[edge[i].v]){ 72 in[father[edge[i].u]]++; 73 } 74 for(int i=1;i<=size;i++) 75 { 76 if(!in[i]&&str){printf("0");return 0;} 77 if(!in[i])str=i; 78 } 79 printf("%d",num[str]); 80 return 0; 81 }
View Code
相关文章推荐
- Java报表工具简介
- 统一关闭域客户端防火墙服务/功能
- SQL计算两个日期的差(天、小时、分、秒)
- 基于STM32的WAV音频格式播放器
- CBPeripheralManager学习笔记
- (一)keil4 MDK 开发环境下编写裸机程序 (参考杨铸 北航) (开发板只需要连接JLNK 就行了)
- startActivity时报错Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVI
- 二维数组名的本质是数组指针
- unity3d 中动画的帧事件
- Fragment集成cordova框架遇到的问题
- vue.js学习
- 获取Linux命令源代码的方法
- 无法打开物理文件 操作系统错误 5:拒绝访问 SQL Sever (附加数据库出错的解决方案)
- Java陷阱一箩筐----面试题集及解答
- 2015年十大热门Android开源新项目
- oracle未归档current redo丢失或损坏
- CC2538之TinyOS例程实验:5-Adc_Temp片内温度读取实验 TinyOS如何直接使用C文件
- servlet回顾
- Base64算法与多版本加密技术
- 改善记忆的方法