样例没过求出QAQ,码风优良,悬赏一关
查看原帖
样例没过求出QAQ,码风优良,悬赏一关
759274
Stevehim楼主2023/10/11 10:22
#include <bits/stdc++.h>
#define MAX(a,b,c) max(a,max(b,c))
#define maxn 1010
//#define int long long/
//关于_ _ _ _,它死了
using namespace std;
const int inf = 2147483647;
//对于两个牧区来说,因为目前两个牧区的直径已经是最短路的
int n, m, s, cnt;
struct Node {
	double x, y;
} a[maxn];
//加边部分
struct EDGE {
	int to, nxt;
	double w;
} e[maxn << 1];
int c[maxn][maxn];
int head[maxn << 1]; //表示以i这个点为起点,第一条边的下标,注意,插入的时候是第几个点的head就是第几个
double dis[maxn][maxn];
bool vis[maxn]; //某个点是否访问
inline void add(int a, int b, double c) {
	e[++cnt].to = b;
	e[cnt].w = c;
	e[cnt].nxt = head[a];
	head[a] = cnt;
}

//最短路部分
//链式前向星也可以用结构体存储
struct node {
	int v;
	double w;
	friend bool operator < (node a, node b) { //重载运算符,使得大根堆变成小根堆,避免了繁琐的greater等等的写法。
		return a.w > b.w;
	}
} tmp;
priority_queue<node> q; //建堆

void dijkstra() {
	for (int i = 1; i <= n; i++)
		dis[s][i] = inf, vis[i] = false; //更改dis、vis数组
	dis[s][s] = 0; //根节点到自己的距离肯定是0
	tmp.v = s; //temp一个,v代表当前结点,w代表权值
	tmp.w = 0;
	q.push(tmp); //先、推一个点
	while (!q.empty()) {
		int u = q.top().v; //取出当前节点
		q.pop();
		if (vis[u]) continue;
		vis[u] = 1; //标记为访问
		for (int i = head[u]; i; i = e[i].nxt) { //遍历这个点链接的点,当nxt数组到最后一项的时候自然会结束,不用担心
			int v = e[i].to;
			double w = e[i].w;
			if (dis[s][v] > dis[s][u] + w) { //long long 处理溢出问题,其实感觉这段代码把dis设为long long还行,不然可以不用加long long
				dis[s][v] = dis[s][u] + w; //这段是松弛操作
				tmp.w = dis[s][v]; //记录下来,可以推了,反正tmp更改了不会有影响
				tmp.v = v;
				q.push(tmp); //入队
			}
		}
	}
}

//染色部分
double diss(int x, int y, int xx, int yy) {
	return sqrt((x - xx) * (x - xx) + (y - yy) * (y - yy));
}
double dir[100100]; //记录块内某点到其他点的最短路
vector<int> Col[maxn]; //记录每个颜色的点
double zhi[10100]; //记录直径
double ans = 0; //记录答案
char ch[2010];
int col[maxn]; //记录每个点是什么颜色
int t;
void dfs(int u, int fa) { //给单个点染色
	for (int i = head[u]; i ; i = e[i].nxt) {
		int to = e[i].to;
		if (fa == u) continue;
		if (!col[to]) {
			col[to] = cnt;
			Col[cnt].push_back(to);
			dfs(to, u);
		}
	}
}

signed main() {
	scanf("%d", &n);
	dijkstra();
	for (int i = 1; i <= n; i++)
		scanf("%lf %lf", &a[i].x, &a[i].y);
	for (int i = 1; i <= n; i++) {
		scanf("%s", ch + 1);
		for (int j = 1; j <= n; j++) {
			if (ch[j] == '1') {
				double w = diss(a[i].x, a[i].y, a[j].x, a[j].y);
				c[i][j] = c[j][i] = w;
				add(i, j, w);
				add(j, i, w);
			}
		}
	}
	for (int i = 1; i <= n; i++) {
		if (!col[i]) { //进行染色,统计出来
			cnt++;
			Col[cnt].push_back(i);
			col[i] = cnt;
			dfs(i, 0);
		}
	}
	s = 1;
	for (int i = 1; i <= n; i++, s = i)
		dijkstra();
	memset(dir, 0, sizeof dir);
	for (int i = 1; i <= cnt; i++) {
		for (int j = 0; j < Col[i].size(); j++) {
			int from = Col[i][j];
			for (int h = j + 1; h < Col[i].size(); h++) {
				int to = Col[i][h];
				if (dis[from][to] == inf) continue; //说明两者之间没有路径
				else dir[h] = max(dir[h], dis[from][to]);
				if (dis[to][from] == inf) continue; //说明两者之间没有路径
				else dir[j] = max(dir[j], dis[to][from]);
			}
			zhi[i] = max(dir[j], zhi[i]);
		}
	}
	ans = 0x3f3f3f3f;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			if (col[i] == col[j]) continue;
			ans = min(ans, MAX(zhi[col[i]], zhi[col[j]], dir[i] + c[i][j] + dir[j]));
		}
	}
	cout << ans;
	return 0;
}
2023/10/11 10:22
加载中...