关于归尘...
查看原帖
关于归尘...
130812
XyzL楼主2020/11/22 18:10

求助... 64分 REorWAREorWA

#include <bits/stdc++.h>

using namespace std;

static char buf[1000000], *p1 = buf, *p2 = buf, obuf[1000000], *p3 = obuf, cc[20];

#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++

#define putchar(x) (p3-obuf<1000000)?(*p3++=x):(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=x)

template <class T>
inline void in(T &x) {
    x = 0;
    register bool f = 0;
    register char c = getchar();
    while (c < 47 || c > 58) {
        f |= (c == '-'), c = getchar();
    }
    while (c > 46 && c < 59) {
        x = (x << 3) + (x << 1) + (c & 15), c = getchar();
    }
    x = f ? (~x + 1) : x;
}

template <typename T>
inline void out(register T x) {
	if (x == 0) {
		putchar('0');
		return ;
	}
    register int len = 0;
    if (x < 0)
        x = -x, putchar('-');
    while (x)
        cc[len++] = x % 10 + '0', x /= 10;
    while (len--)
        putchar(cc[len]);
}

const int MaxN = 2e5 + 5, MaxM = 4e5 + 5;

int T, n, m, q, k, s, cnt, head[MaxN], fa[MaxN], f[MaxN][22], dis[MaxN], hei[MaxN];

bool vis[MaxN];

struct Edge {
	int u, v, h;
	inline bool operator < (const Edge &tmp) const {
		return h > tmp.h;
	}
} e[MaxM];

struct Node {
	int to, next, dist;
} edges[MaxN << 1];

inline void Add_Edge(int u, int v, int w) {
    edges[++cnt].to = v, edges[cnt].next = head[u], edges[cnt].dist = w, head[u] = cnt;
    return ;
}

inline void Dijkstra(int start) {
    memset(dis, 0x7f, sizeof(dis)), memset(vis, false, sizeof(vis));
    priority_queue <pair<int, int>, vector<pair<int,int> >, greater<pair<int,int> > > pq;	
    pq.push(make_pair(dis[start] = 0, start));
    while (!pq.empty()) {
        int u = pq.top().second; 
		pq.pop();
        if(vis[u]) continue;
        vis[u] = true;
        for (register int i = head[u]; i; i = edges[i].next) {
            int v = edges[i].to;
            if (dis[v] > dis[u] + edges[i].dist) {
                dis[v] = dis[u] + edges[i].dist;
                if (!vis[v]) 
					pq.push(make_pair(dis[v],v));
            }
        }
    }
    return ;
}

int Find(int x) {
	return (fa[x] == x) ? x : (fa[x] = Find(fa[x]));
}

inline void Kruskal() {
    sort(e + 1, e + m + 1);
    for (register int i = 1; i <= (n << 1); ++i) 
    	fa[i] = i;
    int sum = n;
    for (register int i = 1; i <= m; ++i) {
        int fx = Find(e[i].u), fy = Find(e[i].v);
        if (fx == fy) continue;
        fa[fx] = fa[fy] = ++sum, hei[sum] = e[i].h;
        dis[sum] = min(dis[fx], dis[fy]);
        f[fx][0] = f[fy][0] = sum;
    }
    for (register int j = 1; (1 << j) <= sum; ++j) 
		for (register int i = 1; i <= sum; ++i) 
			f[i][j] = f[f[i][j - 1]][j - 1];
    return ;
}

inline int Query(int u, int p) {
    for (register int i = 19; i >= 0; --i) 
		if(f[u][i] && hei[f[u][i]] > p) 
			u = f[u][i];
    return dis[u];
}

int main() {
	in(T);
	while (T--) {
		in(n), in(m), cnt = 0;
		memset(head, -1, sizeof(head));
		for (register int i = 1; i <= n; ++i) fa[i] = i;
		for (register int i = 1, u, v, w, h; i <= m; ++i) {
			in(u), in(v), in(w), in(h);
        	Add_Edge(u, v, w), Add_Edge(v, u, w);
        	e[i].u = u, e[i].v = v, e[i].h = h;	
		}
		in(q), in(k), in(s);
		Dijkstra(1); 
		Kruskal();
	    int Ans = 0, v, p;
	    while (q--) {
	        in(v), in(p);
	        v = (v + k * Ans - 1) % n + 1;
	        p = (p + 1LL * k * Ans) % (s + 1);
	        out(Ans = Query(v, p)), putchar('\n');
	    }		
	}
	fwrite(obuf, p3 - obuf, 1, stdout);
	return 0;
}
2020/11/22 18:10
加载中...