洛谷P 1608経路統計解題報告

19484 ワード

パス統計
P1608
技術統計
難易度の向上+/省略-
使用時間1.5 h
コミット回数14
unaccept回数12
ac回数2
題意概括
図の最短の経路と最短の経路の数を求めます
データ範囲
1 ≤ N < = 2000 , 0 ≤ E ≤ N ∗ ( N − 1 ) , 1 ≤ C ≤ 10 1\le N<=2000,0\le E\le N*(N-1),1\le C\le 10 1≤N<=2000,0≤E≤N∗(N−1),1≤C≤10
解法一、
インテリジェントポイント
  • 最短
  • 加算原理
  • dijkstra

  • 解法概括
    走りながら最短で、走るときは加算原理に基づいて案数を統計します
    ピットポイント
  • 構造体は2倍の空間を開いたほうがいいですよ
  • グーグー


  • コード実装
    #include
    #include
    #include
    #define inf 0x3f3f3f3f
    #define maxn 1000100
    using namespace std;
    inline int read()
    {
        long long f=1,k=0;
        char c=getchar();
        while(c>'9'||c<'0')
        {
            if(c=='-')f=-1;
            c=getchar();
        }
        while(c<='9'&&c>='0')k=(k<<1)+(k<<3)+(c^48),c=getchar();
        return f*k;
    }
    struct edge
    {
        int nxt,to,w;
    }p[maxn<<1];
    struct node
    {
        int id,dist;
        bool operator < (const node &s)const{return dist>s.dist;}
    };
    int n,m,cnt;
    int dis[maxn],head[maxn],ans[maxn],use[2020][2020];
    bool vis[maxn];
    void add(int u,int v,int w)
    {
        if(use[u][v]==w)return ;
        use[u][v]=w;
        p[++cnt].nxt=head[u];
        p[cnt].to=v;
        p[cnt].w=w;
        head[u]=cnt;
    }
    void dijkstra()
    {
        priority_queue<node>q;
        memset(dis,inf,sizeof(dis));
        memset(vis,0,sizeof(vis));
        dis[1]=0;
        q.push((node){1,0});
        while(!q.empty())
        {
            node a=q.top();
            q.pop();
            int now=a.id;
            if(!vis[now])
            {
                vis[now]=1;
                for(int i=head[now];i;i=p[i].nxt)
                {
                    int to=p[i].to,w=p[i].w;
                    if(dis[to]==dis[now]+w)ans[to]+=ans[now];
                    if(dis[to]>dis[now]+w)
                    {
                        dis[to]=dis[now]+w;
                        q.push((node){to,dis[to]});
                        ans[to]=ans[now];
                    }
                }
            }
        }
    }
    int main()
    {
        //scanf("%d%d",&n,&m);
        n=read();m=read();
        for(int i=1;i<=m;i++)
        {
            int a=read(),b=read(),c=read();
            //scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
        }
        ans[1]=1;
        dijkstra();
        if(dis[n]==inf)printf("No answer");
        else printf("%d %d",dis[n],ans[n]);
        return 0;
    }
    

    類似テーマ