蒟蒻养成记——简单的数组链表(1)

xiaoxiao2021-02-28  69

Graph

1s,256M

【题目描述】

给你一个n个点m条边的无向图,每个点都有自己的颜色Ci

V(k)是一个点集,集合里面的元素是所有颜色为k的点

定义一个集合Q(k),Q(k)={Cu:Cu!=k,如果存在一条边<u,v>,其中v属于V(k)},通俗一点讲就是Q(k)里面的元素是与V(k)相连的点的各种颜色。注意集合里的元素是不重复的。

你的任务是找到一个最小的k,其中Q(k)是最大的。注意你找的k必须是图里存在的颜色。

【输入格式】

第一行n,m

第二行n个数,为每个点对应的颜色

接下来m行描述了一个无向图,保证无自环

【输出格式】

一个数为使Q(k)最大的k,如有多个就输出最小那个

【输入输出样例】

Input1

6 6 1 1 2 3 5 8 1 2 3 2 1 4 4 3 4 5 4 6

Output1

3

Input2

5 6 4 2 5 2 4 1 2 2 3 3 1 5 3 5 4 3 4

Output2

2

 

【数据约定】

60%数据,n,m,ci<=1000

100%数据: n,m,ci<=10^5

【解法】

本题有两种解法:

第一种解法:看到题目,想到图论。这么多相同颜色的点,那就缩点咯。但作为蒟蒻,TJ算法又不会,只能想想玄学的缩点方法。想想从新构图,每种颜色为一个点,比如u点和v点相连,若b【i】表示i的颜色,则在新的图中,b【u】点和b【v】点相连。最后再计算每个点的度,选取最大度的最小颜色点就行了(就是先选度最大的,如果度相同,选颜色小的)

第二种解法:想想,其实和noip2016的普及组第三题有异曲同工之妙,构造简单的链表(数组实现)链表i 表示与颜色i相连的颜色。具体实现上,f 数组存储数字,ff 数组中的 ff【i】表示ff 的后继为 f中的第i 个。然后读入,若u和v相连,若b【i】表示i的颜色,则b【u】放在链表b【v】的最后,b【v】放在链表b【u】的最后。

【代码】只写了第二种解法

#include<cstdio> #include<cstdlib> #include<iostream> #include<iomanip> using namespace std; int i,j,k,m,n,o,p,js,jl,u,v,ma,mb,nn; int a[1001][1001]; int b[100001]; int c[100001]; int f[200001]; int ff[200001]; int g[100001]; int gg[100001]={0}; int main() { FILE *fin,*fout; fin=fopen("graph.in","rb"); fout=fopen("graph.out","wb"); fscanf(fin,"%d%d",&n,&m); for(int i=1;i<=n;i++) {    fscanf(fin,"%d",&b[i]);    gg[b[i]]=1;    if(b[i]>nn)nn=b[i];     } //========================================================== if(n<=100000)     {     k=0;     for(int i=1;i<=m;i++)    {      fscanf(fin,"%d%d",&u,&v);    if(b[v]!=b[u])    if(g[b[u]]!=0)    {     int kk=g[b[u]];     int pd=0;     while (true)     {     if(f[kk]==b[v])     {     pd=1;     break;     }     if(ff[kk]==0)break;     kk=ff[kk];     }     if(pd==0)     {     c[b[u]]++;     k++;     ff[kk]=k;     f[k]=b[v];     }    }    if(b[v]!=b[u])    if(g[b[v]]!=0)    {     int kk=g[b[v]];     int pd=0;     while (true)     {     if(f[kk]==b[u])     {     pd=1;     break;     }     if(ff[kk]==0)break;     kk=ff[kk];     }     if(pd==0)     {     c[b[v]]++;     k++;     ff[kk]=k;     f[k]=b[u];     }    }    if(b[v]!=b[u])    if(g[b[u]]==0)    {     k++;     g[b[u]]=k;     f[k]=b[v];     c[b[u]]++;    }    if(b[v]!=b[u])    if(g[b[v]]==0)    {     k++;     g[b[v]]=k;     f[k]=b[u];     c[b[v]]++;    }             }         ma=-1;         for(int i=1;i<=nn;i++)    {        if((c[i]>ma)&&(gg[i]==1))        {            ma=c[i];            mb=i;             }         }     } fprintf(fout,"%d",mb); fclose(fin); fclose(fout); return 0; }

转载请注明原文地址: https://www.6miu.com/read-56714.html

最新回复(0)