赞
踩
题意是给你n个点m条边
求出一个三元环(与a相连的边包括b,c)、(与b相连的边包括a,c)(与c相连的边包括a,b)
n,m都是1-4000
一开始觉得暴力枚举复杂度肯定过不了。
随手打了一发交了一次居然才62ms......后来再算算 的确数据规模有点小,直接暴力就可以了
因为需要这个操作 与b相连的所有边中寻找是否存在c,所以直接用set构建邻接表了,查找就可以logn了
暴力枚举每一条度数大于2的边,对所有与它相连的边,查询(b中是否有c,c中是否有b)、如果为真,则abc为三元环
然后一直更新 a.size+b.size+c.size-6 (减6是因为 recognition 是不包括环内的队友的)
复杂度是 o(n)-o(n^2)
最糟糕的情况是 所有边连接在一个点上
-
- #include <cstdio>
- #include <cmath>
- #include <cstring>
- #include <string>
- #include <algorithm>
- #include <iostream>
- #include <queue>
- #include <map>
- #include <set>
- #include <vector>
- using namespace std;
- #define inf 2147483647
- set<int> qq[4005];
- set<int> ::iterator it,tmp,t1,t2;
- int main()
- {
-
- int n,i,j,tt,m;
- scanf("%d%d",&n,&m);
-
- for(i=1;i<=m;i++)
- {
- scanf("%d%d",&tt,&j);
- qq[tt].insert(j);
- qq[j].insert(tt);
- }
- int maxx=inf;
- for (i=1;i<=n;i++)
- {
- if (qq[i].size()<2) continue;
- for (it=qq[i].begin();it!=qq[i].end();it++)
- {
- tmp=it;
- tmp++;
- //printf("%d %d--\n",*it,*tmp);
- for (;tmp!=qq[i].end();tmp++)
- {
- if ( qq[(*it)].count(*tmp)&&qq[(*tmp)].count(*it) )
- {
- int ans=qq[*it].size()+qq[*tmp].size()+qq[i].size();
- if (ans-6<maxx)
- maxx=ans-6;
- }
- }
- }
-
- }
- if (maxx==inf)
- printf("-1\n");
- else
- printf("%d\n",maxx);
-
- return 0;
-
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。