题解 CF366D Dima and Trap Graph
题意
给出一个
题解
萌萌题。
显然最后区间交的左右端点为某两条边的区间的左右端点。
当左端点固定时,右端点的取法是有单调性的,即比最大区间小的区间肯定可以全部到
于是可以枚举每条边,当这条边的区间左端点即最终区间的左端点时,二分右端点的边,判断
判断联通并查集或直接搜都可以,但前者常数大概会小些,跑的快很多。
没啥细节,也挺好写。
复杂度即
#include <bits/stdc++.h>
using namespace std;
namespace IO {
//read and write
} using namespace IO;
const int N = 1e3 + 10, M = 6e3 + 10;
int n, m, ans;
struct edge {
int to, l, r, nxt;
} e[M];
int head[N], cnt;
vector<int> tmp;
bool vis[N];
void add(int u, int v, int l, int r) {
e[++cnt] = (edge){v, l, r, head[u]};
head[u] = cnt;
}
bool dfs(int u, int l, int r) {
if(u == n) return 1;
vis[u] = 1;
for(int i = head[u], v; i; i = e[i].nxt) {
v = e[i].to;
if(vis[v] || e[i].l > l || e[i].r < r) continue;
if(dfs(v, l, r)) return 1;
}
return 0;
}
int main() {
n = read(), m = read();
for(int i = 1, u, v, l, r; i <= m; i++) {
u = read(), v = read(), l = read(), r = read();
add(u, v, l, r), add(v, u, l, r), tmp.push_back(r);
}
sort(tmp.begin(), tmp.end());
for(int i = 1; i <= m; i++) {
int l = lower_bound(tmp.begin(), tmp.end(), e[i << 1].l) - tmp.begin(), r = m - 1, mid = l + r >> 1, res = -1;
while(l <= r) {
memset(vis, 0, sizeof(vis));
mid = l + r >> 1;
if(dfs(1, e[i << 1].l, tmp[mid])) res = mid, l = mid + 1;
else r = mid - 1;
}
if(!~res) continue;
ans = max(ans, tmp[res] - e[i << 1].l + 1);
}
if(!ans) printf("Nice work, Dima!");
else printf("%d", ans);
return 0;
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话