南京网络赛

A题  An Olympian Math Problem:

求S(n) = 1*1! + 2*2! + 3*3! + 4*4! + ... + (n-1)*(n-1)!

链接: https://nanti.jisuanke.com/t/30990

所以直接输出n-1完事

#include <bits/stdc++.h>

using namespace std;

long long n;

int main()
{
    int t;
    scanf("%d", &t);
    while (t--) {
        scanf("%lld", &n);
        printf("%lld\n", n-1);
    }
    return 0;
}
View Code

L. Magical Girl Haze: 

链接: https://nanti.jisuanke.com/t/31001

给你一副有向图,从1出发,可以最多可以让k条路径为0,求到n的最短路径 (K<=10) 

我们发现K特别小.

所以考虑一下Dij, 然后我们把路变为0和不修改路都添加进去, 直接跑就OK了

#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#include <iostream>

using namespace std;

typedef long long ll;

const int maxn = 100500;

struct Edge {
    int lst;
    int to;
    ll val;
}edge[maxn*2];
int head[maxn];
int qsz;

int qn, qk;

inline void add(int u, int v, ll val) {
    edge[qsz].lst = head[u];
    edge[qsz].to  = v;
    edge[qsz].val = val;
    head[u] = qsz++;
}


struct nobe {
    int to;
    int k;
    ll  w;
    nobe () { }
    nobe (int tt, int kk, ll ww) : to(tt), k(kk), w(ww) { }
    bool operator < (const nobe &a) const {
        return w > a.w;
    }
};

bool vis[11][maxn];
ll  dist[11][maxn];

ll Dij(int ed) {
    //cout << ed << endl;
    priority_queue<nobe> pq;
    nobe now;
    int i, u, k, v, j;
    ll w;
    
    for (i=1; i<=qn; ++i) {
        for (j=0; j<=qk; ++j) {
            dist[j][i] = 862621363;
             vis[j][i] = false;
        }
    }
    
    dist[0][1] = 0;
    pq.push(nobe(1, 0, 0));
    while (!pq.empty()) {
        now = pq.top(); pq.pop();
        u = now.to; k = now.k; w = now.w;
        if (vis[k][u]) continue;
        vis[k][u] = true;
        for (i=head[u]; i; i=edge[i].lst) {
            v = edge[i].to;
            if (k<qk && dist[k+1][v] > w) {
                dist[k+1][v] = w;
                pq.push(nobe(v, k+1, w));
            }
            if (dist[k][v] > w + edge[i].val) {
                dist[k][v] = w + edge[i].val;
                pq.push(nobe(v, k, dist[k][v]));
            }
        }
    }
    
    ll res = 0x3fffffffffffffff;
    for (i=0; i<=qk; ++i) 
        res = min(res, dist[i][ed]);
    return res;
}

int main()
{
//    freopen("E:\\input.txt", "r", stdin);
    int t, n, m, k, u, v, c, i;
    scanf("%d", &t);
    while (t--) {
        memset(head, 0, sizeof(head)); qsz = 1;
        scanf("%d%d%d", &n, &m, &k);
        qk = k; qn = n;
        for (i=1; i<=m; ++i) {
            scanf("%d%d%d", &u, &v, &c);
            add(u, v, (ll)c);
        }
        printf("%lld\n", Dij(n));
    }
    
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/cgjh/p/9571607.html