逛公园「NOIP2017」

思路:

几个小问题:

  1. 模板准备了吗?
  2. dp会了吗?
  3. 题目懂了吗?
  4. [luogu]P1144 最短路计数会了吗?

代码:

#include<bits/stdc++.h>

using namespace std;

const int INF = 0x7FFFFFFF;
struct E
{
    int to;
    int wt;
    int nxt;
};
E vedge[200005], sedge[200005];
int vtot, stot;
int vhead[100005], shead[100005];
int n, m, k, p;
int d[100005];
int ans[100005][55];
bool vis[100005][55];
bool flag[100005];
queue<int> q;
queue<int> f;
void vadd(int u, int v, int w)
{
    vtot++;
    vedge[vtot].to = v;
    vedge[vtot].wt = w;
    vedge[vtot].nxt = vhead[u];
    vhead[u] = vtot;
}
void sadd(int u, int v, int w)
{
    stot++;
    sedge[stot].to = v;
    sedge[stot].wt = w;
    sedge[stot].nxt = shead[u];
    shead[u] = stot;
}
int dfs(int a, int b)
{
    if(b < 0)
    {
        return 0;
    }
    else
    {
        if(vis[a][b] == 1)
        {
            return -INF;
        }
        else
        {
            if(ans[a][b] != -1)
            {
                return ans[a][b];
            }
            else
            {
                vis[a][b] = 1;
                int key = 0;
                if(a == n)
                {
                    key++;
                }
                for(int i = vhead[a]; i; i = vedge[i].nxt)
                {
                    int g = vedge[i].to;
                    int y = vedge[i].wt;
                    int u = d[g] - d[a];
                    if(flag[g] == 0)
                    {
                        continue;
                    }
                    int w = dfs(g, b - (y - u));
                    if(w == -INF)
                    {
                        return -INF;
                    }
                    else
                    {
                        key = (key + w) % p;
                    }
                }
                ans[a][b] = key % p;
                vis[a][b] = 0;
                return key;
            }
        }
    }
}
void _spfa()
{
    f.push(n);
    flag[n] = 1;
    while(!f.empty())
    {
        int h = f.front();
        f.pop();
        for(int i = shead[h]; i; i = sedge[i].nxt)
        {
            int g = sedge[i].to;
            if(flag[g] == 0)
            {
                flag[g] = 1;
                f.push(g);
            }
        }
    }
    return;
}
void spfa()
{
    q.push(1);
    d[1] = 0;
    while(!q.empty())
    {
        int h = q.front();
        q.pop();
        for(int i = vhead[h]; i; i = vedge[i].nxt)
        {
            int g = vedge[i].to;
            int y = vedge[i].wt;
            if(d[h] + y < d[g])
            {
                d[g] = d[h] + y;
                q.push(g);
            }
        }
    }
    return;
}
int main()
{
    ios_base::sync_with_stdio(false);
    int t = 0;
    cin >> t;
    while(t--)
    {
        cin >> n >> m >> k >> p;
        memset(vhead, 0, sizeof(vhead));
        memset(shead, 0, sizeof(shead));
        vtot = 0;
        stot = 0;
        memset(vedge, 0, sizeof(vedge));
        memset(sedge, 0, sizeof(sedge));
        for(int i = 1; i <= n; i++)
        {
            flag[i] = 0;
            for(int l = 0; l <= k; l++)
            {
                ans[i][l] = -1;
                vis[i][l] = 0;
            }
        }
        for(int i = 0; i < m; i++)
        {
            int u = 0, v = 0, w = 0;
            cin >> u >> v >> w;
            vadd(u, v, w);
            sadd(v, u, w);
        }
        for(int i = 2; i <= n; i++)
        {
            d[i] = INF;
        }
        spfa();
        _spfa();
        int z = dfs(1, k);
        if(z == -INF)
        {
            cout << -1 << endl;
        }
        else
        {
            cout << z << endl;
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/THE-NAMELESS-SPECTRE/p/11291092.html