比赛 NOIP模拟赛by mzx Day1 评测结果 AAWAWWWTTT
题目名称 零食店 最终得分 30
用户昵称 sxysxy 运行时间 3.064 s
代码语言 C++ 内存使用 15.54 MiB
提交时间 2016-10-19 21:20:59
显示代码纯文本
#include <cstdio>
#include <cstdlib>
#include <cstdarg>
#include <algorithm>
#include <list>
#include <queue>
#include <cstring>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/priority_queue.hpp>
#include <vector>
#include <cctype>
using namespace std;
using namespace __gnu_pbds;
int fast_read()
{
    int r;
    char c;
    bool sig = false;
    while(c = getchar())    
    {
        if(c >= '0' && c <= '9')
        {
            r = c^0x30;
            break;
        }else if(c == '-')sig = true;
    }
    while(isdigit(c = getchar()))
        r = (r<<3)+(r<<1)+(c^0x30);
    return sig? -r:r;
}
#define MAXN 101 
struct edge
{
    int from, to;
    int cost;
};
vector<edge> edges;
vector<int> G[MAXN];
int w[MAXN];
void addedge(int u, int v, int c)
{
    edges.push_back((edge){u, v, c});
    edges.push_back((edge){v, u, c});
    int k = edges.size();
    G[u].push_back(k-2);
    G[v].push_back(k-1);
}
int dist[MAXN][MAXN];
bool done[MAXN];
struct heap_node
{
    int u; int d;
    bool operator<(const heap_node &od)const
    {
        return d > od.d;
    }
    bool operator==(const heap_node &od)const
    {
        return u == od.u && d == od.d;
    }
};
void dijkstra(int s)
{
    memset(done, false, sizeof(done));
    memset(dist[s], 0x6e, sizeof(dist[s]));
    __gnu_pbds::priority_queue<heap_node> q;
    dist[s][s] = 0;
    q.push((heap_node){s, 0});
    while(q.size())
    {
        heap_node x = q.top();
        q.pop();
        int u = x.u;
        if(done[u])continue;
        done[u] = true;
        for(int i = 0; i < G[u].size(); i++)
        {
            edge &e = edges[G[u][i]];
            if(dist[s][e.to] > dist[s][u] + e.cost)
            {
                dist[s][e.to] = dist[s][u] + e.cost;
                q.push((heap_node){e.to, dist[s][e.to]});
            }
        }
    }
}
struct que
{
    int s, c, d;
    int ans;
    inline bool operator<(const que &q) const
    {
        return s < q.s || (s == q.s && c < q.c);
    }
}ques[1000000];
int rank[1000000];
bool rankcmp(int a, int b)
{
    return ques[a] < ques[b];
}
int first[MAXN];
int len[MAXN];

bool vis[MAXN];
inline void dfs_init()
{
    memset(vis, 0, sizeof(vis));
}

int st;
/*
struct distnode
{
    int u;
    bool operator<(const distnode &nd) const
    {
        return dist[st][u] < dist[st][nd.u];
    }
};
*/
#define NULL_TYPE null_mapped_type
typedef tree<heap_node, NULL_TYPE, less<heap_node>, rb_tree_tag, 
            tree_order_statistics_node_update> phs;

phs cnt;
void dfs(int u)
{
    if(vis[u])return;
    //if(w[u] > ques[rank[first[st]+len[st]-1]].c)return;
    //if(dist[st][u] > ques[rank[first[st]+len[st]-1]].d)return;
    vis[u] = true;
    //cnt.insert((distnode){u});
    
    for(int i = 0; i < G[u].size(); i++)
        if(w[edges[G[u][i]].to] <= ques[rank[first[st]+len[st]-1]].c)
            dfs(edges[G[u][i]].to);
}
void dijkstra_singledogmzx(int s)
{
    memset(done, false, sizeof(done));
    memset(dist[s], 0x6e, sizeof(dist[s]));
    __gnu_pbds::priority_queue<heap_node> q;
    dist[s][s] = 0;
    q.push((heap_node){s, 0});
    cnt.insert((heap_node){s, 0});
    
    while(q.size())
    {
        heap_node x = q.top();
        q.pop();
        int u = x.u;
        if(done[u])continue;
        done[u] = true;
        for(int i = 0; i < G[u].size(); i++)
        {
            edge &e = edges[G[u][i]];
            if(!vis[e.to])continue; //刚才没有找到
            if(dist[s][e.to] > dist[s][u] + e.cost)
            {
                dist[s][e.to] = dist[s][u] + e.cost;
                q.push((heap_node){e.to, dist[s][e.to]});
                cnt.insert((heap_node){e.to, dist[s][e.to]});
            }
        }
    }
}
int main()
{
    freopen("snackstore.in", "r", stdin);
    freopen("snackstore.out", "w", stdout);
    int n, m, q;
    n = fast_read();
    m = fast_read();
    q = fast_read();
    for(int i = 1; i <= n; i++)
        w[i] = fast_read();
    for(int i = 0; i < m; i++)
    {
        int a, b, c;
        a = fast_read();
        b = fast_read();
        c = fast_read();
        addedge(a, b, c);
    }
    /*
    for(int i = 1; i <= n; i++)
        dijkstra(i);  //....
    */
    for(int i = 0; i < q; i++)
    {
        rank[i] = i;
        que &q = ques[i];
        q.s = fast_read();
        q.c = fast_read();
        q.d = fast_read();
    }
    sort(rank, rank+q, rankcmp);
    int c = 0;
    for(int i = 0; i < q; i++)
    {
        if(i == 0 || ques[rank[i]].s != ques[rank[i-1]].s)
            first[++c] = rank[i];   //frist[x]表示对于城市x的第一个询问的排名。
        len[c]++;                //len[x]表示对于城市x的询问的个数。
    }
    
    //离线大法好
    for(int i = 1; i <= n; i++)
    {
        /*
        dfs_init();
        st = i;
        dfs(i);
        for(int j = first[i]; j < first[i]+len[i]; j++)
        {
            que &q = ques[rank[j]];
            distnode x = (distnode){101};
            dist[st][101] = q.d+1;
            printf("%d\n", cnt.order_of_key(x));
        }
        cnt.clear();
        */
        dfs_init();
        st = i;
        dfs(i);
        dijkstra_singledogmzx(i);
        for(int j = first[i]; j < first[i]+len[i]; j++)
        {
            que &q = ques[rank[j]];
            q.ans = cnt.size()-cnt.order_of_key((heap_node){233, q.d})+1;
        }
        cnt.clear();
    }
    
    for(int i = 0; i < q; i++)
        printf("%d\n", ques[i].ans);
    return 0;
}