BZOJ 1051 HAOI 2006 受歡迎的牛
阿新 • • 發佈:2018-02-03
body turn .com zoj ++ struct top include 圖片
【題解】
先用tarjan縮點,然後如果某個強聯通分量的出度為0,則該強聯通分量內的點數為答案,否則無解。因為若其他所有的強聯通分量都有邊連向Ai,則Ai必定沒有出邊,否則Ai連向的點所屬的強聯通分量也屬於Ai。
#include<cstdio> #include<algorithm> #define N (50010) #define rg register using namespace std; int n,m,tot,top,color,ans,last[N],st[N],col[N],dfn[N],low[N],num[N]; int degree_out[N]; struct edge{ int to,pre; }e[N]; struct record{ int u,v; }r[N]; inline int read(){ int k=0,f=1; char c=getchar(); while(c<‘0‘||c>‘9‘)c==‘-‘&&(f=-1),c=getchar(); while(‘0‘<=c&&c<=‘9‘)k=k*10+c-‘0‘,c=getchar(); return k*f; } inline int min(int x,int y){return x<y?x:y;} inline void add(int x,int y){e[++tot]=(edge){y,last[x]}; last[x]=tot;} void tarjan(int x){ dfn[x]=low[x]=++tot; st[++top]=x; for(rg int i=last[x],to;i;i=e[i].pre) if(!dfn[to=e[i].to]) tarjan(to),low[x]=min(low[x],low[to]); else if(!col[to]) low[x]=min(low[x],dfn[to]); if(dfn[x]==low[x]) for(color++;st[top+1]!=x;top--) col[st[top]]=color,num[color]++; } int main(){ n=read(); m=read(); for(rg int i=1,u,v;i<=m;i++) u=read(),v=read(),add(u,v),r[i].u=u,r[i].v=v; tot=0; for(rg int i=1;i<=n;i++) if(!col[i]) tarjan(i); for(rg int i=1,u,v;i<=m;i++){ u=r[i].u; v=r[i].v; if(col[u]!=col[v]) degree_out[col[u]]++; } int ans=-1; for(rg int i=1;i<=color;i++) if(!degree_out[i]){ printf("%d\n",num[i]); return 0; } puts("0"); return 0; }
BZOJ 1051 HAOI 2006 受歡迎的牛