CS43(300) Bad Triplet 思维.

来源:互联网 发布:淘宝客服用语技巧 编辑:程序博客网 时间:2024/05/17 04:12
题意:n点m条边的无向图,边的权值都为1
n,m<=1e5,问能否找三个点a,b,c满足dis(a,b)=dis(b,c)=dis(c,a).dis为两点间最短距离.

若存在点X其degree>=3则一定有解,考虑与其相邻的任意三个点A,B,C.
若ABC之间没有边 则A-B=B-C=C-A距离都为2 找到环.
若ABC之间至少有一边条边 假如是A-B 则A-X=X-B=B-A 找到环.

当所有点度数<3 则连通图为一条path或者一个环,前者无解 后者环的长度(定点个数)必须能被3整除.

#include <bits/stdc++.h>using namespace std;typedef long long ll;typedef pair<int,int> ii;const int N=4e5+20,inf=0x3f3f3f3f;int n,m,vis[N];vector<int> e[N],a;map<int,bool> mp[N];void dfs(int u){a.push_back(u);vis[u]=1;for(int i=0;i<e[u].size();i++){int v=e[u][i];if(!vis[v])dfs(v);}}int main(){memset(vis,0,sizeof(vis));int u,v;cin>>n>>m;for(int i=1;i<=m;i++){scanf("%d%d",&u,&v);e[u].push_back(v);e[v].push_back(u);mp[u][v]=true;mp[v][u]=true;}for(int i=1;i<=n;i++){if(e[i].size()>=3){int a=e[i][0],b=e[i][1],c=e[i][2];if(mp[a][b]){printf("%d %d %d\n",i,a,b);return 0;}if(mp[b][c]){printf("%d %d %d\n",i,b,c);return 0;}if(mp[a][c]){printf("%d %d %d\n",i,a,c);return 0;}printf("%d %d %d\n",a,b,c);return 0;}}dfs(1);if(m>=n&&n%3==0)printf("%d %d %d\n",a[0],a[n/3],a[2*n/3]);elseprintf("-1\n");return 0;}