P4819 [中山市选] 杀人游戏
题目大意
详细题目传送门
给出一个有向图,点有黑白颜色,且只有一个黑点。如果选择一个点
思路
首先发现对于一个强联通分量,只要不访问到黑点那么就可以知道这个强联通分量里面的所有点的颜色。所以就先缩点,转成一个 DAG。在转成 DAG 后发现访问所有入度为
感觉就做完了,可是交上去发现是
总结一下,就是在缩点后,求出
- 大小为
。 - 没有出边的强联通分量度数大于
如果存在那么答案变为
代码
#include<bits/stdc++.h>
#define rep(i,a,b) for(register ll i=(a);i<=(b);++i)
#define endl '\n'
using namespace std;
typedef long long ll;
const ll MAXN=1e5+5;
const ll MAXM=3e5+5;
ll n,m;
vector<ll>adj[MAXN];
ll pre[MAXN],low[MAXN],scc[MAXN],ts,sci;
stack<ll>ins;
void dfs(ll u){
pre[u]=low[u]=++ts;
ins.push(u);
for(auto v:adj[u]){
if(!pre[v]){
dfs(v);
low[u]=min(low[u],low[v]);
}else if(!scc[v]){
low[u]=min(low[u],pre[v]);
}
}
if(pre[u]==low[u]){
++sci;
while(true){
ll tp=ins.top();
ins.pop();
scc[tp]=sci;
if(tp==u){
break;
}
}
}
}
vector<ll>g[MAXN];
set<pair<ll,ll>>se;
ll ind[MAXN],sz[MAXN];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>m;
rep(i,1,m){
ll u,v;
cin>>u>>v;
adj[u].push_back(v);
}
rep(i,1,n){
if(!pre[i]){
dfs(i);
}
}
rep(i,1,n){
sz[scc[i]]++;
}
rep(u,1,n){
for(auto v:adj[u]){
if(scc[v]!=scc[u]&&!se.count({scc[u],scc[v]})){
ind[scc[v]]++;
se.insert({scc[u],scc[v]});
g[scc[u]].push_back(scc[v]);
}
}
}
ll val=0,pc=0;
rep(i,1,sci){
if(ind[i]==0){
val++;
if(!pc&&sz[i]==1){
bool gd=true;
for(auto v:g[i]){
if(ind[v]==1){
gd=false;
break;
}
}
if(gd){
pc=1;
}
}
}
}
printf("%0.6lf\n",1-1.0*((val-pc)*1.0/n));
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现