「NOIP模擬」尋找三角形【三元環】
阿新 • • 發佈:2018-12-10
題目描述
在無向圖中,如果三個不同的頂點之間都有邊,則稱他們組成了一個三角形。 在一張無向圖 G 中,有且僅有一個三角形。現在你的任務是找到它。
輸入格式
第一行兩個數 n, mn,m,表示 G 的頂點個數和邊的條數。 接下來 mm 行,每行兩個數 i, ji,j 表示點 ii 和 jj 之間有一條邊。題目保證沒有重邊和自環。
輸出格式
輸出一行,三個整數, i < j < ki
#include <set>
#include <cmath>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
const int N=1e5+5;
int ans[4];
int n,m,s,vis[N],out[N],link[N];
set<int>st;
vector<int>G[N];
inline int read() {
int x=0;char ch=getchar();bool f=0;
while(ch>'9' ||ch<'0'){if(ch=='-')f=1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f?-x:x;
}
int main() {
n=read(),m=read();s=sqrt(m);
for(int i=1;i<=m;i++) {
int x=read(),y=read();
out[x]++,out[y]++;
G[x].push_back(y);
G[y].push_back(x);
st.insert((ll)x*n+y);
st.insert((ll)y*n+x);
}
for (int i=1;i<=n;i++) {
int x=i;vis[x]=1;
for(int j=0;j<G[x].size();j++) link[G[x][j]]=x;
for(int j=0;j<G[x].size();j++) {
int y=G[x][j];
if(vis[y]) continue;
if(out[y]<=s) {
for(int k=0;k<G[y].size();k++) {
int z=G[y][k];
if(link[z]==x) {
ans[1]=x,ans[2]=y,ans[3]=z;
sort(ans+1,ans+1+3);
printf("%d %d %d",ans[1],ans[2],ans[3]);return 0;
}
}
} else {
for(int k=0;k<G[x].size();k++) {
int z=G[x][k];
if(st.find((ll)z*n+y)!=st.end()) {
ans[1]=x,ans[2]=y,ans[3]=z;
sort(ans+1,ans+1+3);
printf("%d %d %d",ans[1],ans[2],ans[3]);return 0;
}
}
}
}
}
return 0;
}