D题:
这题比较的坑,首先题意要明确:
有一些点,给你这些点的颜色(可能重复),再给你这些点构成的图,叫你求 某种颜色 周围 不同的颜色数,输出其中数目最多的那个颜色,也就是这个颜色周围不同的颜色数最多,如果数目相同,输出颜色序号小的那个。
这里有个大坑,题目要求是求 某种颜色 周围,而不是某个点周围,因为有些点的颜色可能相同, 也就是说在求某种颜色周围的时候可能是 多个点的 周围一起求。
当然这种方法比较笨。我们可以把题目给的 节点图 转化为 颜色图 ,对颜色图来说,我们只需要存每一条边的起点终点就行了,然后按起点排序, 把起点相同的边放在一起处理。
这里又有个小trick,在存边的时候,我们还要把 自己 到 自己 的所有边加进去,因为会出现这样的数据
3 1
13 13 1
1 2
如果不加自己的边,那么答案是13,,实际上答案是1.
直接上代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
#include <stack>
#include <queue>
using namespace std;
#define N 310000
#define Dbag printf("haha\n");
#define lson (pos<<1)
#define rson (pos<<1|1)
#define LL long long
struct node
{
int a,b;
}e[N];
int c[N];
int cmp(node a, node b)
{
return a.a < b.a;
}
int main()
{
int n,m;
int cnt = 0;
while(~scanf("%d%d", &n, &m))
{
for(int i = 1; i <= n; i++)
scanf("%d",&c[i]);
for(int i = 0; i < m; i++) //节点图转换为颜色图
{
int a,b;
scanf("%d%d",&a, &b);
e[cnt].a = c[a]; e[cnt++].b = c[b];
e[cnt].a = c[b]; e[cnt++].b = c[a];
}
for(int i = 1; i <= n; i++){e[cnt].a = c[i]; e[cnt++].b = c[i];} //把自己加进去
sort(e, e+cnt, cmp); //排序
int num = 0, ans=-1;
set <int> S;
S.insert(e[0].a);
for(int i = 0; i < cnt; i++)
{
if((i!=0&&e[i].a!=e[i-1].a)||i==cnt-1)
{
if(num<=S.size())
{
if(num==S.size())
{
if(ans>e[i-1].a&&ans!=-1)
ans = e[i-1].a;
if(ans==-1)
ans = e[i-1].a;
}
else
{
num=S.size();
ans=e[i-1].a;
}
}
S.clear();
S.insert(e[i].a);
}
S.insert(e[i].b);
}
printf("%d\n",ans);
}
return 0;
}