题解 [CF1142E] Pink Floyd
题又读错了,两种题意都不会做 /kk
我读成啥了?
题目描述
给定一张 个点的竞赛图。边是有向边,但你不知道方向。
每次询问,你可以获得一条边的方向。
要求出可以到达其余所有点的点的个数。
保证边的方向均匀随机且不随你的询问而改变。
。
求一个期望复杂度较小的做法
然后回到原题:
怎么做呢?
题解建了叶向树形图,于是引出了正解
我胡了个贪心,所以后面死活不会(捂脸
任选一个点为 ,重复一下过程 次:
任选一个未选过的点,询问与 now 之间边的方向
然后令 now 为这条边的起点
想想就知道为啥了
题解维护了所有可能成为答案的叶向树形图的根节点集合
每次任选两个根节点合并
然后考虑这个东西怎么处理有粉色边的情况
那么所有的点可以按照一个关于粉色边的类似拓扑序的顺序加入集合(因为可能有环所以是类似
有环怎么办呢?tarjan 缩点,每个 scc 同时只能有一个点在集合中
于是可以
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define pb push_back
#define ll long long
//#define int long long
int n, m;
queue<int> q;
bool ins[N], vis[N];
vector<int> lst[N];
priority_queue<int> s;
int head[N], dfn[N], low[N], bel[N], sta[N], cnt[N], top, tot, ecnt, now;
struct edge{int from, to, next;}e[N<<1];
inline void add(int s, int t) {e[++ecnt]={s, t, head[s]}; head[s]=ecnt;}
inline int query(int u, int v) {int ans; cout<<"? "<<u<<' '<<v<<endl; fflush(stdout); cin>>ans; return ans;}
void tarjan(int u) {
dfn[u]=low[u]=++tot;
ins[sta[++top]=u]=1;
for (int i=head[u],v; ~i; i=e[i].next) {
v = e[i].to;
if (!dfn[v]) {
tarjan(v);
low[u]=min(low[u], low[v]);
}
else if (ins[v]) low[u]=min(low[u], dfn[v]);
}
if (low[u]==dfn[u]) {
++now;
do {
ins[sta[top]]=0;
bel[sta[top--]]=now;
} while (sta[top+1]!=u);
}
}
void del(int u) {
// cout<<"del: "<<u<<endl;
if (lst[bel[u]].size()) s.push(lst[bel[u]].back()), lst[bel[u]].pop_back();
else vis[bel[u]]=0;
for (int i=head[u],v; ~i; i=e[i].next) if (v=e[i].to, bel[v]!=bel[u]&&--cnt[v]==0) {
if (vis[bel[v]]) lst[bel[v]].pb(v);
else s.push(v), vis[bel[v]]=1;
}
}
signed main()
{
cin>>n>>m;
memset(head, -1, sizeof(head));
for (int i=1,u,v; i<=m; ++i) cin>>u>>v, add(u, v);
for (int i=1; i<=n; ++i) if (!dfn[i]) tarjan(i);
for (int i=1; i<=m; ++i) if (bel[e[i].from]!=bel[e[i].to]) ++cnt[e[i].to];
for (int i=1; i<=n; ++i) if (!cnt[i]) {
if (vis[bel[i]]) lst[bel[i]].pb(i);
else s.push(i), vis[bel[i]]=1;
}
// cout<<"siz: "<<s.size()<<endl;
while (s.size()>1) {
int u=s.top(); s.pop();
int v=s.top(); s.pop();
if (!query(u, v)) swap(u, v);
del(v); s.push(u);
}
cout<<"! "<<s.top()<<endl;
fflush(stdout);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构