标签:
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 30999 | Accepted: 12580 |
Description
Input
Output
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #define inf 0x3f3f3f3f #define mod 10000 typedef long long ll; using namespace std; const int N=10005; const int M=100005; int n,m,cnt,tim,top,cut; int head[N],dfn[N],low[N],stack1[N]; int num[N],du[N],vis[N]; struct man { int to,next; } edg[M]; void init() { memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); memset(num,0,sizeof(num)); memset(du,0,sizeof(du)); cnt=0; tim=1; top=0; cut=0; } void add(int u,int v) { edg[cnt].to=v; edg[cnt].next=head[u]; head[u]=cnt; cnt++; } void dfs(int u,int fa) { dfn[u]=tim; low[u]=tim++; vis[u]=1; stack1[top++]=u; for(int i=head[u]; i!=-1; i=edg[i].next) { int v=edg[i].to; if(!vis[v]) { dfs(v,u); low[u]=min(low[u],low[v]); } else low[u]=min(low[u],low[v]); } if(low[u]==dfn[u]) { cut++; while(top>0&&stack1[top]!=u) { top--; vis[stack1[top]]=2; num[stack1[top]]=cut; } } } int main() { int u,v; while(~scanf("%d%d",&n,&m)) { init(); for(int i=0; i<m; i++) { scanf("%d%d",&u,&v); add(u,v); } for(int i=1; i<=n; i++) { if(!vis[i])dfs(i,0); } for(int i=1; i<=n; i++) { for(int j=head[i]; j!=-1; j=edg[j].next) { if(num[i]!=num[edg[j].to])du[num[i]]++; } } int sum=0,x; for(int i=1; i<=cut; i++) { if(!du[i])sum++,x=i; } if(sum==1) { sum=0; for(int i=1; i<=n; i++) { if(num[i]==x)sum++; } cout<<sum<<endl; } else puts("0"); } return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #define inf 0x3f3f3f3f #define mod 10000 typedef long long ll; using namespace std; const int N=10005; const int M=100005; struct Node { int to,next; }edge1[N*5],edge2[N*5]; //edge1用来存原图G,edge2用来存GT,即逆图 //都是用邻接表来储存的图, int head1[N];//原图的邻接表的头结点 int head2[N];//逆图的邻接表的头结点 int mark1[N],mark2[N]; int tot1,tot2; int cnt1,cnt2,st[N],belong[N]; int num,setNum[N]; struct Edge { int l,r; }e[N*5];//储存边 void add(int a,int b)//添加边a->b,在原图和逆图都需要添加 { edge1[tot1].to=b;edge1[tot1].next=head1[a];head1[a]=tot1++;//邻接表存的原图 edge2[tot2].to=a;edge2[tot2].next=head2[b];head2[b]=tot2++;//邻接表存的逆图 } void DFS1(int x)//深度搜索原图 { mark1[x]=1; for(int i=head1[x];i!=-1;i=edge1[i].next) if(!mark1[edge1[i].to]) DFS1(edge1[i].to); st[cnt1++]=x;//st数组是按照完成时间从小到大排序的 } void DFS2(int x)//深度搜索逆图 { mark2[x]=1; num++; belong[x]=cnt2; for(int i=head2[x];i!=-1;i=edge2[i].next) if(!mark2[edge2[i].to]) DFS2(edge2[i].to); } int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { tot1=tot2=1; for(int i=1;i<=n;i++)//初始化 { head1[i]=head2[i]=-1; mark1[i]=mark2[i]=0; } for(int i=1;i<=m;i++) { int w,v; scanf("%d%d",&w,&v); e[i].l=w;e[i].r=v;//储存边 add(w,v);//建立邻接表 } cnt1=cnt2=1; for(int i=1;i<=n;i++) { if(!mark1[i])DFS1(i); } for(int i=cnt1-1;i>=1;i--) { if(!mark2[st[i]]) { num=0; DFS2(st[i]); setNum[cnt2++]=num; } } int de[N];//计算出度 memset(de,0,sizeof(de)); for(int i=1;i<=m;i++)//计算各个DAG图的出度 { if(belong[e[i].l]!=belong[e[i].r])//原图的边不属于同一连通分支 de[belong[e[i].l]]++; } //计算DAG出度为0的个数 int cnt=0,res; for(int i=1;i<cnt2;i++) if(!de[i]){cnt++;res=i;} if(cnt>1) printf("0\n"); else printf("%d\n",setNum[res]); } return 0; }
标签:
原文地址:http://www.cnblogs.com/jianrenfang/p/5878079.html