题目大意:给定一张有向无环图,现在要求加入一条边,求加入后以1为根的树形图个数
题解:Orz
我的收获:从相似问题出发……
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=100001;
const int P=1e9+7;
int n,m,X,Y;
int in[N],d[N];
ll inv[N],f[N],ans=1;
vector<int> E[N];
void LinearShaker(){
inv[1]=1;
for(int i=2;i<=n;i++) inv[i]=(P-P/i)*inv[P%i]%P;
}
void toposort(){
static int q[N];
int head=0,tail=0;f[Y]=ans;
for(int i=1;i<=n;i++) if(!in[i]) q[++tail]=i;
while(head<tail){
int x=q[++head];
f[x]=f[x]*inv[d[x]]%P;
for(int i=0;i<E[x].size();i++){
f[E[x][i]]=(f[E[x][i]]+f[x])%P;
if(!--in[E[x][i]]) q[++tail]=E[x][i];
}
}
}
void work()
{
for(int i=2;i<=n;i++) ans=ans*d[i]%P;
if(X==Y||Y==1){cout<<ans<<endl;return ;}
toposort();
cout<<(ans-f[X]+P)%P<<endl;
}
void init()
{
scanf("%d%d%d%d",&n,&m,&X,&Y);
for(int i=1;i<=m;i++){
int u,v;scanf("%d%d",&u,&v);
E[u].push_back(v);in[v]++;
}
memcpy(d,in,sizeof(d));d[Y]++;
LinearShaker();
}
int main()
{
init();
work();
return 0;
}
本文介绍了一种算法,用于解决在一个给定的有向无环图中添加一条新边后,以节点1为根的树形图数量计算问题。通过拓扑排序和线性求逆元的方法,实现了高效求解。
424

被折叠的 条评论
为什么被折叠?



