Wannafly Challenge 22 B character path (topological sorting + dp)

Links: https://ac.nowcoder.com/acm/contest/160/B
Source: Cattle-off network

Description Title
to a point containing n and m edges directed acyclic graph (Allow edge, with point represents an integer of 1 to n), each edge of a character, there are several paths meet the Q path in FIG. after string of characters consisting of a rear edge of the strips spaces uppercase letter, full stop '.' end, the middle all lowercase letters, lowercase letters may be 0.
Input Description:
The first line of two integers n, m
Next m lines of two integers a, b and a character C, expressed as a starting point a, the end point b side, the edge of a character C
. 1 ≤ n-, m ≤ 50000
. 1 ≤ a <B ≤ n-
C may be a case letters, or space periods (for convenience with '' ' ' represents a space)
output description:
output an integer representing the result of the answer modulo 232
example an
input
copy
. 6. 11
1 2 A
1 2

. 3. 4
2. 4 B
2. 3 A
2. 3

2. 4 B
. 4. 5.
. 3. 5.
2. 5.
. 5. 6 _
output
copy
16

Ideas:
First, topological sorting,

Why topological sorting it?

Because we know that it is a directed graph, two nodes do not exist after a topological sort, in order topology b follows a and b, and b is a there is an edge point, it does not exist.

Because in the process dp's, one of our state is transferred from the former according to a state, which requires a state must no longer have a change.

That is no after-effect of dynamic programming:

    当前的值只和当前的状态有关,和之前怎么来到这个状态和之后怎么去其他状态都无关。

After we topological sorting again, you may have to transfer to the state side of the character classes.

We define dp states as follows:

dp [i] [0]: i node to the end of the path, the path number includes only spaces.

dp [i] [1]: i node to the end of the path, remove the spaces, the first uppercase character, a lowercase string behind both the number of paths.

dp [i] [0]: '.' i node to the end of the path to the end of the path is a valid number.

See the code transfer equation.

Note: This title has a pit: the so-called capital letter means that after removing spaces, the first character to uppercase characters, can not have multiple capital letters.

See details Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define rt return
#define dll(x) scanf("%I64d",&x)
#define xll(x) printf("%I64d\n",x)
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2) { ans = ans * a % MOD; } a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int *p);
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
struct node {
    int from;
    int to;
    char t;
    node () {}
    node(int ff, int tt, int ty)
    {
        from = ff;
        to = tt;
        t = ty;
    }
};
int n, m;
std::vector<node> son[maxn];
queue<node> q;
node a[maxn];
int in[maxn];
ll dp[maxn][3];
const ll mod = (1ll << 32);
int main()
{
    //freopen("D:\\code\\text\\input.txt","r",stdin);
    //freopen("D:\\code\\text\\output.txt","w",stdout);
    gbtb;
    cin >> n >> m;
    int u, v;
    char t;
    repd(i, 1, m) {
        cin >> u >> v >> t;
        son[u].pb(node(u, v, t));
        in[v]++;
    }
    repd(i, 1, n) {
        if (!in[i]) {
            q.push(node(0, i, '_'));
        }
    }
    int cnt = 0;
    node temp;
    while (!q.empty()) {
        temp = q.front();
        q.pop();
        for (auto x : son[temp.to]) {
            a[++cnt] = x;
            in[x.to]--;
            if (!in[x.to]) {
                q.push(x);
            }
        }
    }

    repd(i, 1, cnt) {
        if (a[i].t == '_') {
            dp[a[i].to][0] += dp[a[i].from][0] + 1;
            dp[a[i].to][1] += dp[a[i].from][1];
            dp[a[i].to][2] += dp[a[i].from][2];
        }
        if (a[i].t == '.') {
            dp[a[i].to][2] += dp[a[i].from][1];
        }
        if (a[i].t <= 'Z' && a[i].t >= 'A') {
            dp[a[i].to][1] += dp[a[i].from][0] + 1;
        }
        if (a[i].t <= 'z' && a[i].t >= 'a') {
            dp[a[i].to][1] += dp[a[i].from][1];
        }
        repd(j, 0, 2) {
            dp[a[i].to][j] %= mod;
        }
    }
    ll ans = 0ll;
    repd(i, 1, n) {
        ans = (ans + dp[i][2]) % mod;
    }
    cout << ans << endl;
    return 0;
}

inline void getInt(int *p)
{
    char ch;
    do {
        ch = getchar();
    } while (ch == ' ' || ch == '\n');
    if (ch == '-') {
        *p = -(getchar() - '0');
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 - ch + '0';
        }
    } else {
        *p = ch - '0';
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 + ch - '0';
        }
    }
}



Guess you like

Origin www.cnblogs.com/qieqiemin/p/11272749.html