Proving Equivalences UVA - 12167
题文:https://vjudge.net/problem/UVA-12167
题解:
很明显,先要缩点。然后画一下图就会发现是入度为0的点和出度为0的点取max。
代码:
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <cmath> #include <iostream> #include <stack> #define MAXN 50100 using namespace std; struct edge{ int first; int next; int to; }a[MAXN*2]; int low[MAXN],dfn[MAXN],have[MAXN],fa[MAXN]; int in[MAXN],out[MAXN]; int num=0,num1=0,num2=0,n,m; stack<int> s; void cl(){ memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(have,0,sizeof(have)); memset(fa,0,sizeof(fa)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); memset(a,0,sizeof(a)); num1=num2=num=0; } void addedge(int from,int to){ a[++num].to=to; a[num].next=a[from].first; a[from].first=num; } void tarjian(int now){ low[now]=dfn[now]=++num1; have[now]=1;s.push(now); for(int i=a[now].first;i;i=a[i].next){ int to=a[i].to; if(!dfn[to]){ tarjian(to); low[now]=min(low[now],low[to]); } else if(have[to]) low[now]=min(low[now],dfn[to]); } if(low[now]==dfn[now]){ int u=-1; num2++; while(u!=now){ u=s.top();s.pop(); have[u]=0; fa[u]=num2; } } } void make(){ for(int now=1;now<=n;now++){ for(int i=a[now].first;i;i=a[i].next){ int to=a[i].to; if(fa[now]!=fa[to]) out[fa[now]]++,in[fa[to]]++; } } } int main() { int t;cin>>t; while(t--){ cl(); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int x,y;scanf("%d%d",&x,&y); addedge(x,y); } while(!s.empty()) s.pop(); for(int i=1;i<=n;i++) if(!dfn[i]) tarjian(i); make(); int x=0,y=0; for(int i=1;i<=num2;i++) if(in[i]==0) x++; for(int i=1;i<=num2;i++) if(out[i]==0) y++; if(num2==1) printf("0\n"); else printf("%d\n",max(x,y)); } return 0; }