关键人物
翻了一下之前(指初二)打算做的难题,但是一直没时间做,几年后翻出来打算水一下。
题目
题目背景
现代社会人们的通信非常方便,社交圈也迅速扩大,可能你不认识某个人,但是通过你的朋友,朋友的朋友……,也能和这个人联系起来。
题目描述
ZEY 在研究人际关系,在这个人际关系中,有 \(n\) 个人,用 \(1\) 到 \(n\) 的编号来表示每一个人,有一些人两两之间是朋友关系,朋友之间可以传递信息,如果 A 和 B 是朋友,B 和 C 是朋友,那么 A 和 C 也能传递信息。但是如果 B 生病了,那么 A 和 C 就联系不上了。那么 B 被称为关键人物。
ZEY 已经知道,在这个人际关系中,每个人都有办法联系到其他的任何一个人,现在他想知道这个人际关系中,哪些人生病会出现有两个人联系不上的情况,即关键人物有哪些。
输入格式
输入分 \(m+1\) 行
第一行输入两个整数 \(n\) 和 \(m\) ,\(n\) 表示人际关系中的人数,m表示朋友关系的数量
接下来m行,每一行两个整数 \(x\) , \(y\) ,表示 \(x\) 和 \(y\) 之间是朋友关系
输出格式
输出1行,将所有关键人物按编号从小到大输出,并用空格隔开
样例 #1
样例输入 #1
3 2
1 2
2 3
样例输出 #1
2
样例 #2
样例输入 #2
5 6
1 2
1 3
3 2
3 4
3 5
5 4
样例输出 #2
3
提示
对于100%的数据,\(1<n≤5×10^4\), \(1<m≤1.5×10^5\)
解法
通过分析题意可得,这就是求无向图的割点。
删了这割点后整个图就不会连通。
然后我们就可以用 Tarjan 水过去了。
如果还是理解不了见 OI-Wiki 。
代码
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cctype>
#include<algorithm>
using std::min;
typedef long long LL;
typedef unsigned long long ULL;
namespace FastIo{
typedef __uint128_t ULLL;
static char buf[100000],*p1=buf,*p2=buf,fw[100000],*pw=fw;
#define gc p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++
inline void pc(const char &ch){
if(pw-fw==100000)fwrite(fw,1,100000,stdout),pw=fw;
*pw++=ch;
}
#define fsh fwrite(fw,1,pw-fw,stdout),pw=fw
struct FastMod{
FastMod(ULL b):b(b),m(ULL((ULLL(1)<<64)/b)){}
ULL reduce(ULL a){
ULL q=(ULL)((ULLL(m)*a)>>64);
ULL r=a-q*b;
return r>=b?r-b:r;
}
ULL b,m;
}HPOP(10);
struct QIO{
char ch;
int st[40];
template<class T>inline void read(T &x){
x=0,ch=gc;
while(!isdigit(ch))ch=gc;
while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=gc;}
}
template<class T>inline void write(T a){
do{st[++st[0]]=HPOP.reduce(a);a/=10;}while(a);
while(st[0])pc(st[st[0]--]^48);
}
}qrw;
}
using namespace FastIo;
#define NUMBER1 50000
#define NUMBER2 150000
#define P(A) A=-~A
#define fione_i(begin,end) for(register int i=begin;i<=end;P(i))
#define tt_i(u) for(register int i=head[u];i;i=e[i].next)
struct EDGE{int next,to;}e[(NUMBER2<<1)+5];
int head[NUMBER1+5],tot(0),cnt(0),n,m,id[NUMBER1+5],low[NUMBER1+5];
bool cut[NUMBER2+5];
inline void add(const int &u,const int &v){e[++tot].next=head[u];e[tot].to=v,head[u]=tot;}
void Tarjan(int u,int fa){
int kid(0);
id[u]=low[u]=++cnt;
tt_i(u){
if(!id[e[i].to]){
Tarjan(e[i].to,fa);
low[u]=min(low[u],low[e[i].to]);
if(low[e[i].to]>=id[u]&&u!=fa)cut[u]=true;
if(u==fa)P(kid);
}
low[u]=min(low[u],id[e[i].to]);
}
if(u==fa&&kid>=2)cut[u]=true;
}
signed main(){
qrw.read(n);
qrw.read(m);
int x,y,ans(0);
fione_i(1,m){
qrw.read(x);
qrw.read(y);
add(x,y);add(y,x);
}
fione_i(1,n)if(!id[i])Tarjan(i,i);
fione_i(1,n)
if(cut[i]){
qrw.write(i);
pc(' ');
}
fsh;
exit(0);
return 0;
}
标签:ch,pw,fw,中二羊,样例,st,关键人物,qrw
From: https://www.cnblogs.com/SHOJYS/p/17095593.html