bzoj 5056: OI游戏

来源:互联网 发布:奇葩说 知乎 那期好看 编辑:程序博客网 时间:2024/06/07 15:56

题意:

求最小路径树计数。

题解

感觉我以前就做过类似的题。。
然而这次我并没有做出来QAQ
我好菜啊

然后呢,你就先跑SPFA
然后看一下哪一条边是答案边就好了

#include<cstdio>#include<algorithm>#include<iostream>#include<queue>#include<cstring>using namespace std;typedef long long LL;const LL MOD=1e9+7;const LL N=55;LL n;char ss[N];struct qq{    LL x,y,z,last;}s[N*N];LL num,last[N];void init (LL x,LL y,LL z){    num++;    s[num].x=x;s[num].y=y;s[num].z=z;    s[num].last=last[x];    last[x]=num;}LL f[N];bool vis[N];void SPFA (){    memset(vis,false,sizeof(vis));    memset(f,127,sizeof(f));    queue<int> q;    q.push(1);f[1]=0;    vis[1]=true;    while (!q.empty())    {        LL x=q.front();q.pop();        for (LL u=last[x];u!=-1;u=s[u].last)        {            LL y=s[u].y;            if (f[y]>f[x]+s[u].z)            {                f[y]=f[x]+s[u].z;                if (vis[y]==false)                {                    vis[y]=true;                    q.push(y);                }            }        }        vis[x]=false;    }}void solve (){    LL ans=1;    for (LL u=2;u<=n;u++)    {        LL tot=0;        for (LL i=last[u];i!=-1;i=s[i].last)        {            LL y=s[i].y;            if (f[u]==f[y]+s[i].z) tot++;        }        ans=(ans*tot)%MOD;    }    printf("%lld\n",ans);}int main(){    num=0;memset(last,-1,sizeof(last));    scanf("%lld",&n);    for (LL u=1;u<=n;u++)    {        scanf("%s",ss+1);        for (LL i=1;i<=n;i++)            if (ss[i]!='0')                init(u,i,ss[i]-'0');    }    SPFA();    solve();    return 0;}