fold的毒瘤题(easy)

题目链接:http://120.78.128.11/Problem.jsp?pid=3250

给出一幅有n(≤50)个点, m(≤500)条边的无向图. 保证任意2点间都至少存在一条路径可以连通, 每条边上都有一个权值Vi(≤500)。不幸的是, 这m条边都被损坏了。fold打算修复其中一些边让一些点连通, 不过, fold并不打算让全部的点连通, 而是选择一些编号特殊的点让它们连通.
fold有q(≤50)次询问, 对于每次询问, 他会选择所有编号在[l,r]之间, 并且编号%p=c的点(保证至少存在2个这样的点), 让这些特殊点连通(任意两个特殊点之间至少存在一条路径).
这里有很多种修复方案, 每种修复方案中都有权值最大的边, fold希望找到这么多方案中: 边权最大值最小的一个方案
你能帮助fold计算出每次询问的最小值是多少吗?
这里询问是独立的, 也就是上一个询问里的修复计划并没有付诸行动.
点的编号从1开始

Solution

暴力并查集

Code

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define fi first
#define se second
#define mst(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const double eps = 1e-9;
const int Mod = 1e9 + 7;
const int MaxN = 1e5 + 5;

vector<int> G;
int n, m, q;
int fa[505];

struct Edge {
	int u, v, c;
}edge[505];

bool cmp(Edge a, Edge b) { return a.c < b.c; }

void init() {
	for(int i = 1; i <= n; i++) fa[i] = i;
	G.clear();
}

int find(int u) {
	if(fa[u] == u) return u;
	return fa[u] = find(fa[u]);
}

int main() 
{
	scanf("%d %d %d", &n, &m, &q);
	for(int i = 1; i <= m; i++) scanf("%d %d %d", &edge[i].u, &edge[i].v, &edge[i].c);
	sort(edge + 1, edge + 1 + m, cmp);
	while(q--) {
		init();
		int L, R, P, C;
		scanf("%d %d %d %d", &L, &R, &P, &C);
		int ans = 0;
		for(int i = L; i <= R; i++)
			if(i % P == C) G.push_back(i);
		bool flag = true;
		for(int i = 1; i <= m && flag; i++) {
			int u = edge[i].u, v = edge[i].v, c = edge[i].c;
			if(find(u) == find(v)) continue;
			fa[find(u)] = find(v);
			flag = false;
			for(int j = 0; j < G.size()-1; j++)
				if(find(G[j]) != find(G[j+1])) flag = true;
			ans = max(ans, c);
		}
		printf("%d\n", ans);
	}
    return 0;
}

你可能感兴趣的:(数据结构)