https://www.luogu.org/blog/KingSann/fou-chang-yong-di-hei-ke-ji-san-yuan-huan-post
商汤在线编程挑战赛SenseTimeAceCoderChallenge
原题做不了,因为这场比赛出了bug,出题人被骂的很惨很惨。
下面是一道类似题,原题是输出是否存在那个唯一三角形,这题是输出编号,本质是一样的题目。
这题难就难在数据范围超级超级大。
顶点数n≤200000
题意:
在无向图中,如果三个不同的顶点之间都有边,则称他们组成了一个三角形。
在一张无向图 G 中,有且仅有一个三角形。现在你的任务是找到它。
输入格式
第一行两个数 n, mn,m,表示 G 的顶点个数和边的条数。
接下来 mm 行,每行两个数 i, ji,j 表示点 ii 和 jj 之间有一条边。题目保证没有重边和自环。
输出格式
输出一行,三个整数, i < j < ki<j<k ,表示三角形的三个顶点。
这题是第一场的D-白色相簿
#include<bits/stdc++.h>
#define test printf("***\n")
#define mlr(a) memset((a),0,sizeof((a)))
#define mmx(a) memset((a),0x3f,sizeof((a)))
#define ka getchar();getchar()
#define ka1 getchar()
#define iis std::ios::sync_with_stdio(false)
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
const int N = 210005;
const int M = 4100005;
const int X = 999983;
const int INF = 1e9;
const double eps = 1e-8;
const int mod = 1e9+7;
struct lp{
int u,v,nex,nexHash;
lp(){}
lp(int a,int b,int c):u(a),v(b),nex(c) {}
}cw[M];
int tot,flag,n,m;
int ar[4];
#define DEBUG
int aa[5005][205];
int dep[N];
int head[N],headHash[X];
int que[N];
int fa[N];
void add(int a,int b){
cw[++tot]=lp(a,b,head[a]);
head[a]=tot;
int h=(a*30000+b)%999983;
cw[tot].nexHash=headHash[h];
headHash[h]=tot;
}
int findHash(int a,int b){
int h=(a*30000+b)%999983;
for(int i=headHash[h];i!=-1;i=cw[i].nexHash){
if((a==cw[i].u)&&(b==cw[i].v)){
return 1;
}
}
return 0;
}
void algo2(){
queue<int>Q;
while(!Q.empty())Q.pop();
for(int i=1;i<=n;++i){
if(dep[i]==0){
Q.push(i);
fa[i]=i;
dep[i]=1;
}
while(!Q.empty()){
int at=Q.front();Q.pop();
for(int i=head[at];i!=-1;i=cw[i].nex){
int to=cw[i].v;
if(dep[to])continue;
dep[to]=1;
Q.push(to);
fa[to]=at;
}
}
}
for(int i=0;i<=tot;++i){
if((cw[i].u!=fa[cw[i].u])&&(cw[i].v!=fa[cw[i].u])&&findHash(cw[i].v,fa[cw[i].u])){
ar[0]=cw[i].u;ar[1]=cw[i].v;ar[2]=fa[cw[i].u];
sort(ar,ar+3);
cout<<ar[0]<<" "<<ar[1]<<" "<<ar[2]<<"\n";
return;
}
}
}
void algo1(){
for(int i=1;i<=m;++i){
for(int j=0;j<=n/30;++j){
if((aa[cw[i*2-1].u][j]&aa[cw[i*2-1].v][j])!=0){
int s=aa[cw[i*2-1].u][j]&aa[cw[i*2-1].v][j];
int k=0;
while(s>0){
s/=2;
++k;
}
ar[0]=cw[i*2-1].u;ar[1]=cw[i*2-1].v;ar[2]=j*30+k-1;
sort(ar,ar+3);
cout<<ar[0]<<" "<<ar[1]<<" "<<ar[2]<<"\n";
return;
}
}
}
}
void init(){
tot=-1;
memset(head,-1,sizeof(head));
memset(headHash,-1,sizeof(headHash));
memset(dep,0,sizeof(dep));
memset(aa,0,sizeof(aa));
}
int main(int argc, char const *argv[])
{
iis;
#ifdef DEBUG
freopen("D:in.in", "r", stdin);
freopen("D:out.out", "w", stdout);
#endif
int a,b;
while(cin>>n>>m){
init();
for(int i=0;i<m;++i){
cin>>a>>b;
add(a,b);add(b,a);
if(n<=5000){
int c=b/30;
int d=b%30;
aa[a][c]+=(1<<d);
c=a/30;
d=a%30;
aa[b][c]+=(1<<d);
}
}
if(n<=5000){
algo1();
}else{
algo2();
}
}
return 0;
}