现在的位置: 首页 > 综合 > 正文

ZOJ 2923

2018年01月14日 ⁄ 综合 ⁄ 共 1306字 ⁄ 字号 评论关闭

这题看了超哥的代码之后一知半懂。大概知道是怎么实现的。其实就是BFS搜索路径,在广搜过程中dis数组维护最短的路径,而dp数组维护路径上有几只虫子和一个节点由几条路径共享。最后通过遍历n节点的dp数组来确定路径数。

源代码来自:http://acm.hust.edu.cn/vjudge/contest/viewSource.action?id=2091664

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <ctime>
using namespace std;

#define LL long long
#define ULL unsigned long long
#define mod 1000000007
#define eps 1e-8
#define MP make_pair

#define mxn 5005
#define mxe 2000005

int first[mxn], vv[mxe], nxt[mxe], e;
int dis[mxn], q[mxn], c[mxn], dp[mxn][55];

void add( int u, int v ) {
    vv[e] = v; nxt[e] = first[u]; first[u] = e++;
}

void bfs( int k ) {
    memset(dis, 0x3f, sizeof(dis));
    memset(dp, 0, sizeof(dp));
    int head = 0, tail = 0;
    dis[1] = 0;
    dp[1][c[1]] = 1;
    q[tail++] = 1;
    while( head < tail ) {
        int u = q[head++];
        for( int j = 0; j <= k; ++j ) if( dp[u][j] )
        for( int i = first[u]; i != -1; i = nxt[i] ) {
            int v = vv[i];
            if( dis[v] == 0x3f3f3f3f ) q[tail++] = v;
            if( dis[v] >= dis[u] + 1 ) {
                dis[v] = dis[u] + 1;
                dp[v][j+c[v]] += dp[u][j];
            }
        }
    }
}

int main()
{
    //ios_base::sync_with_stdio(false);
    int n, m, k, u, v;
    while( scanf( "%d%d%d", &m, &n, &k ) != EOF ) {
        memset(first, -1, sizeof(first)); e = 0;
        for( int i = 1; i <= n; ++i ) {
            scanf( "%d%d", &u, &v );
            c[u] = v;
        }
        for( int i = 1; i <= m; ++i ) {
            scanf( "%d%d", &u, &v );
            add(u, v); add(v, u);
        }
        bfs(k);
        LL ans = 0;
        for( int i = 0; i <= k; ++i ) ans += dp[n][i];
        if( ans == 0 ) puts( "Impossible!" );
        else printf( "%lld\n", ans );
    }
    return 0;
}

【上篇】
【下篇】

抱歉!评论已关闭.