题目大意:
在一个有向图中,求从无入度的点到达无出度的点的路径条数(单点除外!!!)
n≤100000,E≤200000
n
≤
100000
,
E
≤
200000
这题较水,定义个
F[i]
F
[
i
]
表示以节点i为终点的路径条数,拓扑顺推或反建图DFS
最后统计无出度的点(重要的事情说三遍:单点除外!!! 单点除外!!! 单点除外!!!)
#include<cstdio>
#include<cstring>
#define LL long long
using namespace std;
const int maxn=(1e5)+5,maxE=(2e5)+5,TT=1e8;
int n,m,que[maxn],cnt[maxn];LL ans,f[maxn];
int tot,son[maxE],nxt[maxE],lnk[maxn],in[maxn],out[maxn];
void add_e(int x,int y){son[++tot]=y,nxt[tot]=lnk[x],lnk[x]=tot,out[x]++,in[y]++;}
char gt(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
int read(){
int ret=0;bool f=0;char ch=gt();
while(ch<'0'||ch>'9') f|=(ch=='-'),ch=gt();
while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=gt();
return f?-ret:ret;
}
//struct ff{
// int len,a[205];
// ff(){memset(a,0,sizeof a),len=0;}
// ff(int x){
// len=0,memset(a,0,sizeof a);
// do{
// a[++len]=x%TT,x/=TT;
// }while(x);
// }
// ff operator +(const ff b){
// ff c;c.len=len>b.len?len:b.len;
// for(int i=1;i<=c.len;i++){
// c.a[i]+=a[i]+b.a[i];
// c.a[i+1]+=c.a[i]/TT;
// c.a[i]%=TT;
// }
// if(c.a[c.len+1]) c.len++;
// return c;
// }
// void write(){
// while(len>1&&!a[len]) len--;
// printf("%d",a[len]);
// for(int i=len-1;i;i--) printf("%08d",a[i]);
// printf("\n");
// }
//}f[maxn],ans;
void topo(){
int hed=0,tal=0;
for(int i=1;i<=n;i++){
cnt[i]=in[i];
if(!in[i]) que[++tal]=i,f[i]=1;
}
while(hed!=tal){
for(int j=lnk[que[++hed]];j;j=nxt[j]){
f[son[j]]=f[son[j]]+f[que[hed]];
if(!--cnt[son[j]]) que[++tal]=son[j];
}
}
for(int i=1;i<=n;i++) if(!out[i]&&in[i]) ans=ans+f[i];
}
int main(){
n=read(),m=read();
for(int i=1;i<=m;i++){
int x=read(),y=read();
add_e(x,y);
}
// ans=0;
topo();
// ans.write();
printf("%lld\n",ans);
return 0;
}
PS:题目没说,害我白码了高精度!!!