bzoj 5056

不想写题解...这题就是在跑最短路的时候记录下每个点最短路树上可能的父亲,然后把每个点的父亲数量乘起来就行了

代码:

 
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#define ll long long
using namespace std;
const ll mode=1000000007;
struct Edge
{
    int nxt;
    int to;
    int val;
}edge[500005];
struct node
{
    int p,v;
    node (){}
    node (int x,int y):p(x),v(y){}
    friend bool operator < (node a,node b)
    {
        return a.v>b.v;
    }
};
int head[55];
int dis[55];
bool vis[55];
int cnt=1;
char ch[55];
int n;
vector <int> f[55];
void add(int l,int r,int w)
{
    edge[cnt].nxt=head[l];
    edge[cnt].to=r;
    edge[cnt].val=w;
    head[l]=cnt++;
}
void diji()
{
    priority_queue <node> M;
    memset(dis,0x3f,sizeof(dis));
    dis[1]=0;
    M.push(node(1,0));
    while(!M.empty())
    {
        node temp=M.top();
        M.pop();
        int u=temp.p;
        if(vis[u])continue;
        vis[u]=1;
        for(int i=head[u];i;i=edge[i].nxt)
        {
            int to=edge[i].to;
            if(dis[to]>dis[u]+edge[i].val)
            {
                f[to].clear();
                f[to].push_back(u);
                dis[to]=dis[u]+edge[i].val;
                M.push(node(to,dis[to]));
            }else if(dis[to]==dis[u]+edge[i].val)f[to].push_back(u);
        }
    }
    ll ans=1;
    for(int i=2;i<=n;i++)ans=ans*f[i].size()%mode;
    printf("%lld\n",ans);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",ch+1);
        for(int j=1;j<=n;j++)if(ch[j]-'0'>0)add(i,j,ch[j]-'0');
    }
    diji();
    return 0;
}

 

posted @ 2019-07-04 15:02  lleozhang  Views(120)  Comments(0Edit  收藏  举报
levels of contents