K-pop

Gym - 102020K
https://vjudge.net/problem/Gym-102020K/origin

//二分+搜索找最大流量,再跑最短路求最小花费
//复杂度是 mlog(prime_cnt) + mlogn

namespace IO {
	const int MX = 4e7;
	char buf[MX]; int ch, sz;
	void begin() {
		ch = 0;
		sz = fread(buf, 1, MX, stdin);
	}
	inline bool read(int& t) {
		while (ch < sz && buf[ch] != '-' && (buf[ch] < '0' || buf[ch] > '9')) ch++;
		if (ch >= sz)	return false;
		bool flag = 0; if (buf[ch] == '-')	flag = 1, ch++;
		for (t = 0; ch < sz && '0' <= buf[ch] && buf[ch] <= '9'; ++ch)
			t = t * 10 + buf[ch] - '0';
		if (flag) t = -t;
		return true;
	}
}
using namespace IO;

const int maxn = 1e5 + 10;
const int maxm = 5e5 + 10;
int n, m, O, D;

int prime[maxm], pcnt = 0;
bool isprime[maxm * 10];
void get_prime() {
	prime[++pcnt] = 0;
	prime[++pcnt] = 1;
	int up = maxm * 10;
	for (int i = 2; i < up; ++i) {
		if (!isprime[i])	prime[++pcnt] = i;
		for (int j = 3; j <= pcnt && i * prime[j] < up; ++j) {
			isprime[i * prime[j]] = 1;
			if (i % prime[j] == 0)	break;
		}
	}
}

int head[maxn], to[maxm], nxt[maxm], cost[maxm], ecnt = 0;
inline void add(int u, int v, int w) {
	to[++ecnt] = v; nxt[ecnt] = head[u]; cost[ecnt] = w; head[u] = ecnt;
}

struct node {
	int u, v, a, p;
	bool operator < (const node& b) const {
		return a > b.a;
	}
}p[maxm];

bool vis[maxn];
void init(int n) {
	memset(vis, 0, (n + 1));  ecnt = 0;
	memset(head, 0, (n + 1) << 2);
}
bool dfs(int s) {
	vis[s] = 1;
	for (int i = head[s]; i; i = nxt[i]) {
		if (vis[to[i]])	continue; 
		if (to[i] == D)	return 1;
		if (dfs(to[i]))	return 1;
	}
	return 0;
}

int Binary() {
	int l = 1, r = pcnt, mid;
	while (l <= r) {
		init(n);
		mid = l + r >> 1;
		int num = prime[mid];
		for (int i = 1; i <= m; ++i)
			if (p[i].a >= num)	add(p[i].u, p[i].v, p[i].p);
			else break;
		if (dfs(O))	l = mid + 1;
		else r = mid - 1;
	}
	return prime[l - 1];
}

ll dis[maxn];
void dij(int s) {
	priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>> > que;
	que.push({ 0, s });
	memset(dis, 0x3f, (n + 1) << 3);
	dis[s] = 0;
	while (!que.empty()) {
		int top = que.top().second;
		que.pop();
		if (vis[top])	continue;
		vis[top] = 1;
		if (vis[D])	break;
		for (int i = head[top]; i; i = nxt[i]) {
			int id = to[i]; if (vis[id])	continue;
			if (dis[id] > dis[top] + cost[i]) {
				dis[id] = dis[top] + cost[i];
				que.push({ dis[id], to[i] });
			}
		}
	}
}

signed main() {
	//freopen("s.txt", "r", stdin);
	get_prime();
	begin();
	read(n); read(m); read(O); read(D);
	for (int i = 1; i <= m; ++i) {
		read(p[i].u); read(p[i].v); read(p[i].a); read(p[i].p);
	}
	sort(p + 1, p + 1 + m);
	int num = Binary();
	init(n);
	for (int i = 1; i <= m; ++i)
		if (p[i].a >= num)	add(p[i].u, p[i].v, p[i].p);
		else break;
	dij(O);
	printf("%d %lld\n", num, num * dis[D]);
}



posted @ 2021-03-03 20:37  wansheking  阅读(14)  评论(0)    收藏  举报